diff --git a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn deleted file mode 100644 index d0d548e4f9460ab00c373eeb8d73c7d98825050e..0000000000000000000000000000000000000000 --- a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2022 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. -import("//build/test.gni") - -module_output_path = "data_object/impl" - -############################################################################### -config("module_private_config") { - visibility = [ ":*" ] - - include_dirs = [ - "../../../../../frameworks/innerkitsimpl/include/adaptor", - "../../../../../frameworks/innerkitsimpl/include/common", - "../../../../../frameworks/innerkitsimpl/include/communicator", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - ] -} - -ohos_distributedtest("DistributedTest") { - module_out_path = module_output_path - - configs = [ ":module_private_config" ] - sources = [] - sources += [ "distributed_test.cpp" ] - - external_deps = [ - "access_token:libaccesstoken_sdk", - "access_token:libnativetoken", - "access_token:libtoken_setproc", - "c_utils:utils", - "dsoftbus:softbus_client", - "hilog:libhilog", - "ipc:ipc_core", - ] - - deps = [ - "//foundation/distributeddatamgr/data_object/interfaces/innerkits:distributeddataobject_static", - "//third_party/googletest:gtest_main", - ] -} - -ohos_distributedtest("DistributedTestAgent") { - module_out_path = module_output_path - configs = [ ":module_private_config" ] - sources = [ "distributed_test_agent.cpp" ] - - external_deps = [ - "access_token:libaccesstoken_sdk", - "access_token:libnativetoken", - "access_token:libtoken_setproc", - "c_utils:utils", - "dsoftbus:softbus_client", - "hilog:libhilog", - "ipc:ipc_core", - ] - - deps = [ - "//foundation/distributeddatamgr/data_object/interfaces/innerkits:distributeddataobject_static", - "//third_party/googletest:gtest_main", - ] -} - -############################################################################### -group("distributedtest") { - testonly = true - - deps = [ - ":DistributedTest", - ":DistributedTestAgent", - ] -} - -############################################################################### - diff --git a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test.cpp b/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test.cpp deleted file mode 100644 index 99685b97961c293440761c1400fa2bf97a54b6c4..0000000000000000000000000000000000000000 --- a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (c) 2022 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 - -#include -#include -#include "distributed_object.h" -#include "distributed_objectstore.h" -#include "objectstore_errors.h" -#include "distributed_major.h" -#include "softbus_adapter.h" -#include "accesstoken_kit.h" -#include "nativetoken_kit.h" -#include "hilog/log.h" -#include "ipc_skeleton.h" -#include "token_setproc.h" - -using namespace testing::ext; -using namespace OHOS; -using namespace OHOS::HiviewDFX; -using namespace OHOS::DistributeSystemTest; -using namespace OHOS::ObjectStore; -using namespace OHOS::Security::AccessToken; - -namespace { -constexpr int MAX_RETRY_TIMES = 100; -constexpr int INTERVAL = 200; -constexpr HiLogLabel LABEL = {LOG_CORE, 0, "DistributedTest"}; -const std::string DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; -const std::string BUNDLENAME = "com.example.myapplication"; -const std::string SESSIONID = "123456"; - -void GrantPermissionNative() -{ - const char **perms = new const char *[2]; - perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; - perms[1] = "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER"; - TokenInfoParams infoInstance = { - .dcapsNum = 0, - .permsNum = 2, - .aclsNum = 0, - .dcaps = nullptr, - .perms = perms, - .acls = nullptr, - .processName = "distributed_object", - .aplStr = "system_basic", - }; - uint64_t tokenId = GetAccessTokenId(&infoInstance); - SetSelfTokenID(tokenId); - AccessTokenKit::ReloadNativeTokenInfo(); -} - -class DistributedTest : public DistributeTest { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -class ObjectWatcherImpl : public ObjectWatcher { -public: - bool GetDataStatus(); - void OnChanged(const std::string &sessionid, const std::vector &changedData) override; - virtual ~ObjectWatcherImpl(); -private: - bool dataChanged_ = false; -}; - -class StatusNotifierImpl : public StatusNotifier { -public: - std::string GetOnlineStatus(); - void OnChanged( - const std::string &sessionId, const std::string &networkId, const std::string &onlineStatus) override; - virtual ~StatusNotifierImpl(); -private: - std::string onlineStatus_ = "offline"; -}; - -ObjectWatcherImpl::~ObjectWatcherImpl() -{ -} - -bool ObjectWatcherImpl::GetDataStatus() -{ - return dataChanged_; -} - -void ObjectWatcherImpl::OnChanged(const std::string &sessionid, const std::vector &changedData) -{ - if (changedData.empty()) { - HiLog::Info(LABEL, "empty change"); - return; - } - HiLog::Info(LABEL, "start %{public}s, %{public}s", sessionid.c_str(), changedData.at(0).c_str()); - dataChanged_ = true; -} - -StatusNotifierImpl::~StatusNotifierImpl() -{ -} - -std::string StatusNotifierImpl::GetOnlineStatus() -{ - return onlineStatus_; -} - -void StatusNotifierImpl::OnChanged(const std::string &sessionId, - const std::string &networkId, - const std::string &onlineStatus) -{ - onlineStatus_ = onlineStatus; -} - -void DistributedTest::SetUpTestCase(void) -{ -} - -void DistributedTest::TearDownTestCase(void) -{ -} - -void DistributedTest::SetUp(void) -{ - GrantPermissionNative(); -} - -void DistributedTest::TearDown(void) -{ -} - -void WaitStatus(std::shared_ptr notifierPtr, const std::string &status) -{ - int times = 0; - while (times < MAX_RETRY_TIMES && notifierPtr->GetOnlineStatus() != status) { - std::this_thread::sleep_for(std::chrono::milliseconds(INTERVAL)); - times++; - } -} - -void WaitDataChangeStatus(std::shared_ptr watcherPtr) -{ - int times = 0; - while (times < MAX_RETRY_TIMES && !watcherPtr->GetDataStatus()) { - std::this_thread::sleep_for(std::chrono::milliseconds(INTERVAL)); - times++; - } -} - -/** - * @tc.name: SendMessage - * @tc.desc: normal testcase of DistributedTest - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, SendMessageCase, TestSize.Level1) -{ - std::string returnValue; - std::string msgBuf = "recall"; - int ret = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - - EXPECT_TRUE(ret > 0); - EXPECT_EQ(returnValue, "recall Message"); -} - -/** - * @tc.name: DistributedTest_Put_Get_001 - * @tc.desc: test DistributedTest Put & Get. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, Put_Get_001, TestSize.Level1) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - uint32_t ret = object->PutString("name", "zhangsan"); - EXPECT_EQ(SUCCESS, ret); - - std::string newvalue = ""; - ret = object->GetString("name", newvalue); - EXPECT_EQ(SUCCESS, ret); - - std::string msgBuf = "GetItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - EXPECT_EQ(returnValue, "zhangsan"); - - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_Put_Get_002 - * @tc.desc: test DistributedTest Put & Get. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, Put_Get_002, TestSize.Level1) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - auto watcherPtr = std::make_shared(); - uint32_t ret = objectStore->Watch(object, watcherPtr); - EXPECT_EQ(SUCCESS, ret); - - std::string msgBuf = "PutItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - EXPECT_EQ(returnValue, "PutSuccsess"); - - WaitDataChangeStatus(watcherPtr); - EXPECT_TRUE(watcherPtr->GetDataStatus()); - - double value = 0.0; - object->GetDouble("salary", value); - EXPECT_EQ(value, 100.5); - - ret = objectStore->UnWatch(object); - EXPECT_EQ(SUCCESS, ret); - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_save_001 - * @tc.desc: test DistributedTest saveRemote. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, save_001, TestSize.Level1) -{ - std::string sessionId = SESSIONID; - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - - DistributedObject *object = objectStore->CreateObject(sessionId); - EXPECT_NE(nullptr, object); - uint32_t ret = object->PutString("name", "zhangsan"); - EXPECT_EQ(SUCCESS, ret); - - std::vector devices = SoftBusAdapter::GetInstance()->GetDeviceList(); - std::vector deviceIds; - for (auto item : devices) { - deviceIds.push_back(item.deviceId); - } - std::string networkId =SoftBusAdapter::GetInstance()->ToNodeID(deviceIds[0]); - ret = object->Save(networkId); - EXPECT_EQ(SUCCESS, ret); - ret = objectStore->DeleteObject(sessionId); - EXPECT_EQ(SUCCESS, ret); - - std::string msgBuf = "GetItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - EXPECT_EQ(returnValue, "zhangsan"); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_RevokeSave_001 - * @tc.desc: test DistributedTest RevokeSave. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, RevokeSave_001, TestSize.Level1) -{ - std::string msgBuf = "RevokeSave"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - - std::string sessionId = SESSIONID; - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(sessionId); - EXPECT_NE(nullptr, object); - std::string getValue = "GetItem"; - uint32_t ret = object->GetString("name", getValue); - EXPECT_NE(SUCCESS, ret); - EXPECT_NE(getValue, returnValue); - - ret = objectStore->DeleteObject(sessionId); - EXPECT_EQ(SUCCESS, ret); -} - -/** - * @tc.name: DistributedTest_Watch_001 - * @tc.desc: test DistributedTest Watch - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, Watch_001, TestSize.Level1) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - auto watcherPtr = std::make_shared(); - uint32_t ret = objectStore->Watch(object, watcherPtr); - EXPECT_EQ(SUCCESS, ret); - - std::string msgBuf = "PutItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - - WaitDataChangeStatus(watcherPtr); - EXPECT_TRUE(watcherPtr->GetDataStatus()); - ret = objectStore->UnWatch(object); - EXPECT_EQ(SUCCESS, ret); - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_UnWatch_001 - * @tc.desc: test DistributedTest UnWatch. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, UnWatch_001, TestSize.Level1) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - auto watcherPtr = std::make_shared(); - uint32_t ret = objectStore->Watch(object, watcherPtr); - EXPECT_EQ(SUCCESS, ret); - - ret = objectStore->UnWatch(object); - EXPECT_EQ(SUCCESS, ret); - - std::string msgBuf = "PutItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - - EXPECT_NE(nullptr, watcherPtr); - EXPECT_FALSE(watcherPtr->GetDataStatus()); - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_SetStatusNotifier_001 - * @tc.desc: test DistributedTest SetStatusNotifier. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, SetStatusNotifier_001, TestSize.Level1) -{ - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - auto notifierPtr = std::make_shared(); - uint32_t ret = objectStore->SetStatusNotifier(notifierPtr); - EXPECT_EQ(ret, SUCCESS); - - std::string msgBuf = "PutItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - - EXPECT_TRUE(result > 0); - - WaitStatus(notifierPtr, "online"); - EXPECT_EQ(notifierPtr->GetOnlineStatus(), "online"); - - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} - -/** - * @tc.name: DistributedTest_SetStatusNotifier_002 - * @tc.desc: test DistributedTest SetStatusNotifier. - * @tc.type: FUNC - */ -HWTEST_F(DistributedTest, SetStatusNotifier_002, TestSize.Level1) -{ - std::string msgBuf = "PutItem"; - std::string returnValue; - int result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - EXPECT_NE(nullptr, objectStore); - DistributedObject *object = objectStore->CreateObject(SESSIONID); - EXPECT_NE(nullptr, object); - - auto notifierPtr = std::make_shared(); - uint32_t ret = objectStore->SetStatusNotifier(notifierPtr); - EXPECT_EQ(ret, SUCCESS); - auto watcherPtr = std::make_shared(); - ret = objectStore->Watch(object, watcherPtr); - - WaitStatus(notifierPtr, "online"); - EXPECT_EQ(notifierPtr->GetOnlineStatus(), "online"); - - WaitDataChangeStatus(watcherPtr); - EXPECT_TRUE(watcherPtr->GetDataStatus()); - - msgBuf = "SaveRemote"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - returnValue = szreturnbuf; - return true; - }); - EXPECT_TRUE(result > 0); - - WaitStatus(notifierPtr, "restored"); - EXPECT_EQ(notifierPtr->GetOnlineStatus(), "restored"); - - ret = objectStore->DeleteObject(SESSIONID); - EXPECT_EQ(SUCCESS, ret); - - msgBuf = "DestroyObject"; - result = SendMessage(AGENT_NO::ONE, msgBuf, msgBuf.size(), - [&](const std::string &szreturnbuf, int rlen)->bool { - return true; - }); - EXPECT_TRUE(result > 0); -} -} - -int main(int argc, char *argv[]) -{ - HiLog::Info(LABEL, "begin"); - g_pDistributetestEnv = new DistributeTestEnvironment("major.desc"); - testing::AddGlobalTestEnvironment(g_pDistributetestEnv); - testing::GTEST_FLAG(output) = "xml:./"; - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test_agent.cpp b/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test_agent.cpp deleted file mode 100644 index c8bb4766f15a8aa7104b4a84d268b54c33876e98..0000000000000000000000000000000000000000 --- a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/distributed_test_agent.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2022 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 - -#include -#include -#include "distributed_object.h" -#include "distributed_objectstore.h" -#include "objectstore_errors.h" -#include "hilog/log.h" -#include "distributed_agent.h" -#include "ipc_skeleton.h" -#include "accesstoken_kit.h" -#include "nativetoken_kit.h" -#include "token_setproc.h" -#include "softbus_adapter.h" - -using namespace testing; -using namespace testing::ext; -using namespace OHOS; -using namespace OHOS::DistributeSystemTest; -using namespace OHOS::HiviewDFX; -using namespace OHOS::ObjectStore; -using namespace OHOS::Security::AccessToken; - -namespace { -constexpr HiLogLabel LABEL = {LOG_CORE, 0, "DistributedTestAgent"}; -const std::string DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; -const std::string BUNDLENAME = "com.example.myapplication"; -const std::string SESSIONID = "123456"; -constexpr int MAX_RETRY_TIMES = 100; -constexpr int INTERVAL = 200; - -void GrantPermissionNative() -{ - const char **perms = new const char *[2]; - perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; - perms[1] = "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER"; - TokenInfoParams infoInstance = { - .dcapsNum = 0, - .permsNum = 2, - .aclsNum = 0, - .dcaps = nullptr, - .perms = perms, - .acls = nullptr, - .processName = "distributed_object", - .aplStr = "system_basic", - }; - uint64_t tokenId = GetAccessTokenId(&infoInstance); - SetSelfTokenID(tokenId); - AccessTokenKit::ReloadNativeTokenInfo(); -} - -class DistributedTestAgent : public DistributedAgent { -public: - DistributedTestAgent(); - ~DistributedTestAgent(); - virtual bool SetUp(); - virtual bool TearDown(); - virtual int OnProcessMsg(const std::string &strMsg, int len, std::string &strReturnValue, int returnBufL); - int ProcessMsg(const std::string &strMsg, std::string &strReturnValue); - int RecallMessage(const std::string &strMsg, std::string &strReturnValue); - int PutItem(const std::string &strMsg, std::string &strReturnValue); - int GetItem(const std::string &strMsg, std::string &strReturnValue); - int RevokeSave(const std::string &strMsg, std::string &strReturnValue); - int DestroyObject(const std::string &strMsg, std::string &strReturnValue); - int SaveRemote(const std::string &strMsg, std::string &strReturnValue); - static DistributedObjectStore *object_; - static DistributedObject *objectSession_; -private: - using MsgFunc = int (DistributedTestAgent::*)(const std::string &, std::string &); - std::map msgFunMap_; -}; - -class ObjectWatcherImpl : public ObjectWatcher { -public: - bool GetDataStatus(); - void OnChanged(const std::string &sessionid, const std::vector &changedData) override; - virtual ~ObjectWatcherImpl(); -private: - bool dataChanged_ = false; -}; - -class StatusNotifierImpl : public StatusNotifier { -public: - std::string GetOnlineStatus(); - void OnChanged( - const std::string &sessionId, const std::string &networkId, const std::string &onlineStatus) override; - virtual ~StatusNotifierImpl(); -private: - std::string onlineStatus_ = "offline"; -}; - -ObjectWatcherImpl::~ObjectWatcherImpl() -{ -} - -bool ObjectWatcherImpl::GetDataStatus() -{ - return dataChanged_; -} - -void ObjectWatcherImpl::OnChanged(const std::string &sessionid, const std::vector &changedData) -{ - if (changedData.empty()) { - HiLog::Info(LABEL, "empty change"); - return; - } - HiLog::Info(LABEL, "start %{public}s, %{public}s", sessionid.c_str(), changedData.at(0).c_str()); - dataChanged_ = true; -} - -StatusNotifierImpl::~StatusNotifierImpl() -{ -} - -std::string StatusNotifierImpl::GetOnlineStatus() -{ - return onlineStatus_; -} - -void StatusNotifierImpl::OnChanged(const std::string &sessionId, - const std::string &networkId, - const std::string &onlineStatus) -{ - onlineStatus_ = onlineStatus; -} - -DistributedObjectStore *DistributedTestAgent::object_ = nullptr; -DistributedObject *DistributedTestAgent::objectSession_ = nullptr; - -DistributedTestAgent::DistributedTestAgent() -{ -} - -DistributedTestAgent::~DistributedTestAgent() -{ -} - -bool DistributedTestAgent::SetUp() -{ - GrantPermissionNative(); - msgFunMap_["recall"] = &DistributedTestAgent::RecallMessage; - msgFunMap_["PutItem"] = &DistributedTestAgent::PutItem; - msgFunMap_["GetItem"] = &DistributedTestAgent::GetItem; - msgFunMap_["RevokeSave"] = &DistributedTestAgent::RevokeSave; - msgFunMap_["DestroyObject"] = &DistributedTestAgent::DestroyObject; - msgFunMap_["SaveRemote"] = &DistributedTestAgent::SaveRemote; - return true; -} - -bool DistributedTestAgent::TearDown() -{ - return true; -} - -int DistributedTestAgent::OnProcessMsg(const std::string &strMsg, int len, std::string &strReturnValue, int returnBufL) -{ - return DistributedTestAgent::ProcessMsg(strMsg, strReturnValue); -} - -int DistributedTestAgent::ProcessMsg(const std::string &strMsg, std::string &strReturnValue) -{ - int index = strMsg.find(","); - std::string argsMsg = strMsg.substr(0, index); - std::map::iterator it = msgFunMap_.find(argsMsg); - if (it != msgFunMap_.end()) { - MsgFunc MsgFunc = msgFunMap_[argsMsg]; - return (this->*MsgFunc)(strMsg, strReturnValue); - } - return -1; -} - -int DistributedTestAgent::RecallMessage(const std::string &strMsg, std::string &strReturnValue) -{ - strReturnValue = "recall Message"; - return strReturnValue.size(); -} - -int DistributedTestAgent::PutItem(const std::string &strMsg, std::string &strReturnValue) -{ - std::string sessionId = SESSIONID; - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - if (objectStore != nullptr) { - DistributedObject *object = objectStore->CreateObject(sessionId); - DistributedTestAgent::object_ = objectStore; - auto notifierPtr = std::make_shared(); - objectStore->SetStatusNotifier(notifierPtr); - int times = 0; - while (times < MAX_RETRY_TIMES && notifierPtr->GetOnlineStatus() != "online") { - std::this_thread::sleep_for(std::chrono::milliseconds(INTERVAL)); - times++; - } - uint32_t status = object->PutDouble("salary", 100.5); - if (status != SUCCESS) { - return -1; - } - DistributedTestAgent::objectSession_ = object; - strReturnValue = "PutSuccsess"; - } - return strReturnValue.size(); -} - -int DistributedTestAgent::GetItem(const std::string &strMsg, std::string &strReturnValue) -{ - std::string sessionId = SESSIONID; - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - if (objectStore != nullptr) { - DistributedObject *object = objectStore->CreateObject(sessionId); - DistributedTestAgent::object_ = objectStore; - - auto watcherPtr = std::make_shared(); - objectStore->Watch(object, watcherPtr); - int times = 0; - while (times < MAX_RETRY_TIMES && !watcherPtr->GetDataStatus()) { - std::this_thread::sleep_for(std::chrono::milliseconds(INTERVAL)); - times++; - } - std::string getValue = "GetItem"; - uint32_t status = object->GetString("name", getValue); - if (status != SUCCESS) { - return -1; - } - objectStore->UnWatch(object); - strReturnValue = getValue; - } - return strReturnValue.size(); -} - -int DistributedTestAgent::RevokeSave(const std::string &strMsg, std::string &strReturnValue) -{ - std::string sessionId = SESSIONID; - std::string putValue = "zhangsan"; - DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(BUNDLENAME); - if (objectStore != nullptr) { - DistributedObject *object = objectStore->CreateObject(sessionId); - if (object != nullptr) { - object->PutString("name", putValue); - std::vector devices = SoftBusAdapter::GetInstance()->GetDeviceList(); - std::string networkId = SoftBusAdapter::GetInstance()->ToNodeID(devices[0].deviceId); - object->Save(networkId); - uint32_t status = object->RevokeSave(); - if (status != SUCCESS) { - strReturnValue = "RevokeSave failed."; - return -1; - } - objectStore->DeleteObject(sessionId); - } - } - strReturnValue = putValue; - return strReturnValue.size(); -} - -int DistributedTestAgent::DestroyObject(const std::string &strMsg, std::string &strReturnValue) -{ - if (DistributedTestAgent::object_ != nullptr) { - DistributedTestAgent::object_->DeleteObject(SESSIONID); - DistributedTestAgent::object_ = nullptr; - strReturnValue = "DestroyObjectDone"; - } - return strReturnValue.size(); -} - -int DistributedTestAgent::SaveRemote(const std::string &strMsg, std::string &strReturnValue) -{ - if (DistributedTestAgent::objectSession_ != nullptr) { - std::vector devices = SoftBusAdapter::GetInstance()->GetDeviceList(); - std::string networkId = SoftBusAdapter::GetInstance()->ToNodeID(devices[0].deviceId); - DistributedTestAgent::objectSession_->Save(networkId); - strReturnValue = "SaveRemote succsess"; - } else { - strReturnValue = "recall SaveRemote"; - } - - return strReturnValue.size(); -} - -} -int main() -{ - DistributedTestAgent obj; - if (obj.SetUp()) { - obj.Start("agent.desc"); - obj.Join(); - } else { - HiLog::Error(LABEL, "Init environment failed."); - } - if (obj.TearDown()) { - return 0; - } else { - HiLog::Error(LABEL, "Clear environment failed."); - return -1; - } -} diff --git a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h index 17010e62f9406239a96bb542601b000ebe1e3185..3c90ddb502fcfeecc158ce95f616655ee0dc382a 100644 --- a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h +++ b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h @@ -37,6 +37,8 @@ private: std::weak_ptr uvQueue_; }; + static void ExecUvWork(uv_work_t *work, int uvstatus); + napi_env env_; std::shared_mutex mutex_{}; // key is callback,value is list of args diff --git a/data_object/frameworks/jskitsimpl/src/common/js_util.cpp b/data_object/frameworks/jskitsimpl/src/common/js_util.cpp index dc32640617b337e616673f8c8abf3ad993600af4..d12446b02e2e1810ea0e13cca47d787690e862dc 100644 --- a/data_object/frameworks/jskitsimpl/src/common/js_util.cpp +++ b/data_object/frameworks/jskitsimpl/src/common/js_util.cpp @@ -54,7 +54,7 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, std::string &out) { size_t maxLen = STR_MAX_LENGTH; napi_status status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); - if (maxLen <= 0) { + if (status != napi_ok || maxLen <= 0) { return napi_generic_failure; } char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; diff --git a/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp b/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp index 5f3ef20429aa785adcf25d59820b6a8403287d96..0298d7bade4e63d54ba651ac872c732f37431d0a 100644 --- a/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp +++ b/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp @@ -27,6 +27,23 @@ UvQueue::~UvQueue() LOG_DEBUG("no memory leak for queue-callback"); } +void UvQueue::ExecUvWork(uv_work_t *work, int uvstatus) +{ + UvEntry *entry = static_cast(work->data); + auto queue = entry->uvQueue_.lock(); + if (queue != nullptr) { + std::unique_lock cacheLock(queue->mutex_); + for (auto &item : queue->args_) { + item.first(queue->env_, item.second); + } + queue->args_.clear(); + } + delete entry; + work->data = nullptr; + delete work; + work = nullptr; +} + void UvQueue::CallFunction(Process process, void *argv) { if (process == nullptr || argv == nullptr) { @@ -40,6 +57,7 @@ void UvQueue::CallFunction(Process process, void *argv) } work->data = new (std::nothrow)UvEntry { weak_from_this() }; if (work->data == nullptr) { + delete work; LOG_ERROR("no memory for UvEntry"); return; } @@ -57,22 +75,7 @@ void UvQueue::CallFunction(Process process, void *argv) } int ret = uv_queue_work( - loop_, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int uvstatus) { - UvEntry *entry = static_cast(work->data); - auto queue = entry->uvQueue_.lock(); - if (queue != nullptr) { - std::unique_lock cacheLock(queue->mutex_); - for (auto &item : queue->args_) { - item.first(queue->env_, item.second); - } - queue->args_.clear(); - } - delete entry; - entry = nullptr; - delete work; - work = nullptr; - }); + loop_, work, [](uv_work_t *work) {}, UvQueue::ExecUvWork); if (ret != 0) { if (work->data != nullptr) { UvEntry *uvEntry = static_cast(work->data); diff --git a/data_object/interfaces/jskits/distributed_data_object.js b/data_object/interfaces/jskits/distributed_data_object.js index 388106537f6b80c08a0bc6c9b454bbf23a52556e..0d24323b876010cfa53d1b70a4f12da906576a6d 100644 --- a/data_object/interfaces/jskits/distributed_data_object.js +++ b/data_object/interfaces/jskits/distributed_data_object.js @@ -125,6 +125,44 @@ function newDistributed(obj) { return new Distributed(obj); } +function getObjectValue(object, key) { + console.info('start get ' + key); + let result = object.get(key); + if (typeof result === 'string') { + if (result.startsWith(STRING_TYPE)) { + result = result.substr(STRING_TYPE.length); + } else if (result.startsWith(COMPLEX_TYPE)) { + result = JSON.parse(result.substr(COMPLEX_TYPE.length)); + } else if (result.startsWith(NULL_TYPE)) { + result = null; + } else { + console.error('error type'); + } + } + console.info('get success'); + return result; +} + +function setObjectValue(object, key, newValue) { + console.info('start set ' + key + ' ' + newValue); + if (typeof newValue === 'object') { + let value = COMPLEX_TYPE + JSON.stringify(newValue); + object.put(key, value); + console.info('set ' + key + ' ' + value); + } else if (typeof newValue === 'string') { + let value = STRING_TYPE + newValue; + object.put(key, value); + console.info('set ' + key + ' ' + value); + } else if (newValue == null) { + let value = NULL_TYPE; + object.put(key, value); + console.info('set ' + key + ' ' + value); + } else { + object.put(key, newValue); + console.info('set ' + key + ' ' + newValue); + } +} + function joinSession(version, obj, objectId, sessionId, context) { console.info('start joinSession ' + sessionId); if (obj == null || sessionId == null || sessionId === '') { @@ -149,40 +187,10 @@ function joinSession(version, obj, objectId, sessionId, context) { enumerable: true, configurable: true, get: function () { - console.info('start get ' + key); - let result = object.get(key); - if (typeof result === 'string') { - if (result.startsWith(STRING_TYPE)) { - result = result.substr(STRING_TYPE.length); - } else if (result.startsWith(COMPLEX_TYPE)) { - result = JSON.parse(result.substr(COMPLEX_TYPE.length)); - } else if (result.startsWith(NULL_TYPE)) { - result = null; - } else { - console.error('error type'); - } - } - console.info('get success'); - return result; + return getObjectValue(object, key); }, set: function (newValue) { - console.info('start set ' + key + ' ' + newValue); - if (typeof newValue === 'object') { - let value = COMPLEX_TYPE + JSON.stringify(newValue); - object.put(key, value); - console.info('set ' + key + ' ' + value); - } else if (typeof newValue === 'string') { - let value = STRING_TYPE + newValue; - object.put(key, value); - console.info('set ' + key + ' ' + value); - } else if (newValue == null) { - let value = NULL_TYPE; - object.put(key, value); - console.info('set ' + key + ' ' + value); - } else { - object.put(key, newValue); - console.info('set ' + key + ' ' + newValue); - } + setObjectValue(object, key, newValue); } }); if (obj[key] !== undefined) { diff --git a/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability_module.cpp b/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability_module.cpp index 9e0d46b7a17f52d0cd1ad94669b6cd58be631ad3..55bf7e6d9695c11bfbf6f7041cb338b12f24dd06 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability_module.cpp +++ b/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability_module.cpp @@ -19,17 +19,18 @@ extern const char _binary_datashare_ext_ability_js_start[]; extern const char _binary_datashare_ext_ability_js_end[]; extern const char _binary_datashare_ext_ability_abc_start[]; extern const char _binary_datashare_ext_ability_abc_end[]; +static void NAPI_application_DataShareExtensionAbility_AutoRegister(); + +static napi_module g_ExtensionModule = { + .nm_version = 0, + .nm_filename = "application/libdatashareextensionability_napi.so/DataShareExtensionAbility.js", + .nm_modname = "application.DataShareExtensionAbility", +}; extern "C" __attribute__((constructor)) void NAPI_application_DataShareExtensionAbility_AutoRegister() { - auto moduleManager = NativeModuleManager::GetInstance(); - NativeModule newModuleInfo = { - .name = "application.DataShareExtensionAbility", - .fileName = "application/libdatashareextensionability_napi.so/DataShareExtensionAbility.js", - }; - - moduleManager->Register(&newModuleInfo); + napi_module_register(&g_ExtensionModule); } extern "C" __attribute__((visibility("default"))) diff --git a/data_share/frameworks/js/napi/datashare_ext_ability_context/datashare_ext_ability_context_module.cpp b/data_share/frameworks/js/napi/datashare_ext_ability_context/datashare_ext_ability_context_module.cpp index 145456c2d85567eceaf93e4a3380748802ec651b..64b5d737712f3b6e498551fb9033f54165364ef7 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability_context/datashare_ext_ability_context_module.cpp +++ b/data_share/frameworks/js/napi/datashare_ext_ability_context/datashare_ext_ability_context_module.cpp @@ -19,17 +19,18 @@ extern const char _binary_datashare_ext_ability_context_js_start[]; extern const char _binary_datashare_ext_ability_context_js_end[]; extern const char _binary_datashare_ext_ability_context_abc_start[]; extern const char _binary_datashare_ext_ability_context_abc_end[]; +static void NAPI_application_DataShareExtensionAbilityContext_AutoRegister(); + +static napi_module g_ExtensionContextModule = { + .nm_version = 0, + .nm_filename = "application/libdatashareextensionabilitycontext_napi.so/DataShareExtensionAbilityContext.js", + .nm_modname = "application.DataShareExtensionAbilityContext", +}; extern "C" __attribute__((constructor)) void NAPI_application_DataShareExtensionAbilityContext_AutoRegister() { - auto moduleManager = NativeModuleManager::GetInstance(); - NativeModule newModuleInfo = { - .name = "application.DataShareExtensionAbilityContext", - .fileName = "application/libdatashareextensionabilitycontext_napi.so/DataShareExtensionAbilityContext.js", - }; - - moduleManager->Register(&newModuleInfo); + napi_module_register(&g_ExtensionContextModule); } extern "C" __attribute__((visibility("default"))) diff --git a/data_share/frameworks/native/common/src/datashare_result_set.cpp b/data_share/frameworks/native/common/src/datashare_result_set.cpp index 4ad05d1aa2117e2358a15d6a782ce1f97a7fb4ab..c52b349d15a9fe01df05feb5e1b25accbde7b6e8 100644 --- a/data_share/frameworks/native/common/src/datashare_result_set.cpp +++ b/data_share/frameworks/native/common/src/datashare_result_set.cpp @@ -215,7 +215,7 @@ int DataShareResultSet::GetString(int columnIndex, std::string &value) value = std::string(sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull)); return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) { - return E_ERROR; + return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) { int64_t tempValue = cellUnit->cell.longValue; value = std::to_string(tempValue); diff --git a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h index bd8b333a7f1bee33816dbd302ce65384d810ab57..564397dd8de914ac8cc0541221c5b8107f86fc11 100644 --- a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h +++ b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h @@ -241,12 +241,12 @@ public: isBlockWaiting_ = blockWaiting; } - NativeValue* GetAsyncResult() const + napi_value GetAsyncResult() const { return callbackData_; } - void SetAsyncResult(NativeValue* asyncResult) + void SetAsyncResult(napi_value asyncResult) { callbackData_ = asyncResult; } @@ -307,15 +307,15 @@ private: struct AsyncPoint { std::shared_ptr context; }; - NativeValue* CallObjectMethod(const char *name, NativeValue * const *argv = nullptr, size_t argc = 0, + napi_value CallObjectMethod(const char *name, napi_value const *argv = nullptr, size_t argc = 0, bool isAsync = true); - NativeValue *CallObjectMethod( - const char *name, NativeValue **argv, size_t argc, std::shared_ptr asyncContext); + napi_value CallObjectMethod( + const char *name, napi_value const *argv, size_t argc, std::shared_ptr asyncContext); void GetSrcPath(std::string &srcPath); napi_value MakePredicates(napi_env env, const DataSharePredicates &predicates); - static NativeValue* AsyncCallback(NativeEngine* engine, NativeCallbackInfo* info); - static NativeValue* AsyncCallbackWithContext(NativeEngine* engine, NativeCallbackInfo* info); - void CheckAndSetAsyncResult(NativeEngine* engine); + static napi_value AsyncCallback(napi_env env, napi_callback_info info); + static napi_value AsyncCallbackWithContext(napi_env env, napi_callback_info info); + void CheckAndSetAsyncResult(napi_env env); static void NotifyToDataShareService(); static void UnWrapBusinessError(napi_env env, napi_value info, DatashareBusinessError &businessError); static napi_valuetype UnWrapPropertyType(napi_env env, napi_value info, @@ -325,7 +325,7 @@ private: JsRuntime& jsRuntime_; std::unique_ptr jsObj_; bool isBlockWaiting_ = false; - NativeValue* callbackData_ = nullptr; + napi_value callbackData_ = nullptr; int callbackResultNumber_ = -1; std::string callbackResultString_ = ""; std::vector callbackResultStringArr_ = {}; diff --git a/data_share/frameworks/native/provider/include/js_datashare_ext_ability_context.h b/data_share/frameworks/native/provider/include/js_datashare_ext_ability_context.h index 4c3492ac5a7d2e3fef73545523bd5c326a9b490a..34fe0f0eeba668979a4f0cd99fa5ab27ab40d7f2 100644 --- a/data_share/frameworks/native/provider/include/js_datashare_ext_ability_context.h +++ b/data_share/frameworks/native/provider/include/js_datashare_ext_ability_context.h @@ -20,12 +20,12 @@ #include "ability_connect_callback.h" #include "datashare_ext_ability_context.h" -class NativeEngine; -class NativeValue; +#include "napi/native_api.h" + namespace OHOS { namespace DataShare { using namespace AbilityRuntime; -NativeValue* CreateJsDataShareExtAbilityContext(NativeEngine& engine, +napi_value CreateJsDataShareExtAbilityContext(napi_env env, std::shared_ptr context); } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp index a5b231f04a7b4f6b955a4cdd1ca6160fb23b05d5..c24a492b212dd52a87fd77e41a4b9b9490b32511 100644 --- a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp +++ b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp @@ -35,18 +35,16 @@ void DataShareUvQueue::LambdaForWork(uv_work_t *work, int uvstatus) return; } auto *entry = static_cast(work->data); - { - std::unique_lock lock(entry->mutex); - if (entry->func) { - entry->func(); - } - entry->done = true; - if (!entry->purge) { - entry->condition.notify_all(); - return; - } + std::unique_lock lock(entry->mutex); + if (entry->func) { + entry->func(); + } + entry->done = true; + if (entry->purge) { + DataShareUvQueue::Purge(work); + } else { + entry->condition.notify_all(); } - DataShareUvQueue::Purge(work); } void DataShareUvQueue::SyncCall(NapiVoidFunc func, NapiBoolFunc retFunc) @@ -56,27 +54,34 @@ void DataShareUvQueue::SyncCall(NapiVoidFunc func, NapiBoolFunc retFunc) LOG_ERROR("invalid work."); return; } - auto *uvEntry =new UvEntry {env_, std::move(func), false, false, {}, {}, {}}; - work->data = uvEntry; + work->data = new UvEntry {env_, std::move(func), false, false, {}, {}, std::move(retFunc)}; + auto status = uv_queue_work( + loop_, work, [](uv_work_t *work) {}, LambdaForWork); + if (status != napi_ok) { + LOG_ERROR("queue work failed"); + DataShareUvQueue::Purge(work); + return; + } + bool noNeedPurge = false; - do{ - std::unique_lock lock(uvEntry->mutex); - auto status = uv_queue_work(loop_, work, [](uv_work_t *work) {}, LambdaForWork); - if (status != napi_ok) { - LOG_ERROR("queue work failed"); - break; + auto *uvEntry = static_cast(work->data); + { + if (uvEntry == nullptr) { + LOG_ERROR("invalid uvEntry."); + return; } + std::unique_lock lock(uvEntry->mutex); if (uvEntry->condition.wait_for(lock, std::chrono::seconds(WAIT_TIME), [uvEntry] { return uvEntry->done; })) { LOG_INFO("function ended successfully"); } - + CheckFuncAndExec(uvEntry->retFunc); if (!uvEntry->done && !uv_cancel((uv_req_t*)&work)) { LOG_ERROR("uv_cancel failed."); uvEntry->purge = true; noNeedPurge = true; } - } while (false); - CheckFuncAndExec(retFunc); + } + if (!noNeedPurge) { DataShareUvQueue::Purge(work); } diff --git a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp index b428cfaf2fa30d3234a5225191866ecd2f1c0530..462eb5cefbf4be95ffea83a5391cbf72b40cb7a0 100644 --- a/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/js_datashare_ext_ability.cpp @@ -39,7 +39,10 @@ namespace DataShare { using namespace AbilityRuntime; namespace { constexpr int INVALID_VALUE = -1; -const std::string ASYNC_CALLBACK_NAME = "AsyncCallback"; +static constexpr int32_t MAX_ARGC = 6; +static constexpr int32_t MIN_ARGC = 2; +constexpr const char ASYNC_CALLBACK_NAME[] = "AsyncCallback"; +constexpr int CALLBACK_LENGTH = sizeof(ASYNC_CALLBACK_NAME) - 1; } bool MakeNapiColumn(napi_env env, napi_value &napiColumns, const std::vector &columns); @@ -76,16 +79,15 @@ void JsDataShareExtAbility::Init(const std::shared_ptr &reco moduleName.append("::").append(abilityInfo_->name); LOG_INFO("module:%{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str()); HandleScope handleScope(jsRuntime_); - auto& engine = jsRuntime_.GetNativeEngine(); + napi_env env = jsRuntime_.GetNapiEnv(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, - abilityInfo_->compileMode == CompileMode::ES_MODULE); + jsObj_ = jsRuntime_.LoadModule( + moduleName, srcPath, abilityInfo_->hapPath, abilityInfo_->compileMode == CompileMode::ES_MODULE); if (jsObj_ == nullptr) { LOG_ERROR("Failed to get jsObj_, moduleName:%{public}s.", moduleName.c_str()); return; } - - NativeObject* obj = ConvertNativeValueTo(jsObj_->Get()); + napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { LOG_ERROR("Failed to get JsDataShareExtAbility object, moduleName:%{public}s.", moduleName.c_str()); return; @@ -96,40 +98,30 @@ void JsDataShareExtAbility::Init(const std::shared_ptr &reco LOG_ERROR("Failed to get context, moduleName:%{public}s.", moduleName.c_str()); return; } - - NativeValue* contextObj = CreateJsDataShareExtAbilityContext(engine, context); + napi_value contextObj = CreateJsDataShareExtAbilityContext(env, context); auto contextRef = jsRuntime_.LoadSystemModule("application.DataShareExtensionAbilityContext", &contextObj, 1); - contextObj = contextRef->Get(); + contextObj = contextRef->GetNapiValue(); context->Bind(jsRuntime_, contextRef.release()); - obj->SetProperty("context", contextObj); - - auto nativeObj = ConvertNativeValueTo(contextObj); - if (nativeObj == nullptr) { - LOG_ERROR("Failed to get datashare extension ability native object, moduleName:%{public}s.", - moduleName.c_str()); - return; - } - LOG_INFO("Set datashare extension ability context pointer is nullptr: %{public}d", context.get() == nullptr); - nativeObj->SetNativePointer(new std::weak_ptr(context), - [](NativeEngine*, void* data, void*) { - LOG_INFO("Finalizer for weak_ptr datashare extension ability context is called"); + napi_set_named_property(env, obj, "context", contextObj); + napi_wrap(env, contextObj, new std::weak_ptr(context), + [](napi_env, void *data, void *) { + LOG_DEBUG("Finalizer for weak_ptr datashare extension ability context is called"); delete static_cast*>(data); - }, nullptr); + }, nullptr, nullptr); } void JsDataShareExtAbility::OnStart(const AAFwk::Want &want) { Extension::OnStart(want); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { return; } napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); - NativeValue* nativeWant = reinterpret_cast(napiWant); - NativeValue* argv[] = {nativeWant}; + napi_value argv[] = {napiWant}; std::shared_ptr context = std::make_shared(); context->isNeedNotify_ = true; CallObjectMethod("onCreate", argv, sizeof(argv)/sizeof(argv[0]), context); @@ -141,7 +133,7 @@ sptr JsDataShareExtAbility::OnConnect(const AAFwk::Want &want) Extension::OnConnect(want); sptr remoteObject = new (std::nothrow) DataShareStubImpl( std::static_pointer_cast(shared_from_this()), - reinterpret_cast(&jsRuntime_.GetNativeEngine())); + jsRuntime_.GetNapiEnv()); if (remoteObject == nullptr) { LOG_ERROR("No memory allocated for DataShareStubImpl"); return nullptr; @@ -149,26 +141,23 @@ sptr JsDataShareExtAbility::OnConnect(const AAFwk::Want &want) return remoteObject->AsObject(); } -void JsDataShareExtAbility::CheckAndSetAsyncResult(NativeEngine* engine) +void JsDataShareExtAbility::CheckAndSetAsyncResult(napi_env env) { + napi_valuetype type = napi_undefined; auto result = GetAsyncResult(); - auto type = result->TypeOf(); - if (type == NATIVE_NUMBER) { - int32_t value = OHOS::AppExecFwk::UnwrapInt32FromJS(reinterpret_cast(engine), - reinterpret_cast(result)); + napi_typeof(env, result, &type); + if (type == napi_valuetype::napi_number) { + int32_t value = OHOS::AppExecFwk::UnwrapInt32FromJS(env, result); SetResult(value); - } else if (type == NATIVE_STRING) { - std::string value = OHOS::AppExecFwk::UnwrapStringFromJS(reinterpret_cast(engine), - reinterpret_cast(result)); + } else if (type == napi_valuetype::napi_string) { + std::string value = OHOS::AppExecFwk::UnwrapStringFromJS(env, result); SetResult(value); - } else if (type == NATIVE_OBJECT) { + } else if (type == napi_valuetype::napi_object) { ResultSetBridge::Creator *proxy = nullptr; - napi_unwrap(reinterpret_cast(engine), reinterpret_cast(result), - reinterpret_cast(&proxy)); + napi_unwrap(env, result, reinterpret_cast(&proxy)); if (proxy == nullptr) { std::vector value; - OHOS::AppExecFwk::UnwrapArrayStringFromJS(reinterpret_cast(engine), - reinterpret_cast(result), value); + OHOS::AppExecFwk::UnwrapArrayStringFromJS(env, result, value); SetResult(value); } else { std::shared_ptr value = proxy->Create(); @@ -183,63 +172,68 @@ void JsDataShareExtAbility::CheckAndSetAsyncResult(NativeEngine* engine) } } -NativeValue* JsDataShareExtAbility::AsyncCallback(NativeEngine* engine, NativeCallbackInfo* info) +napi_value JsDataShareExtAbility::AsyncCallback(napi_env env, napi_callback_info info) { - if (engine == nullptr || info == nullptr) { + if (env == nullptr || info == nullptr) { LOG_ERROR("invalid param."); return nullptr; } - if (info->argc < 2 || info->argv[0] == nullptr || info->argv[1] == nullptr) { - LOG_ERROR("invalid args."); - return engine->CreateUndefined(); + napi_value self = nullptr; + size_t argc = MAX_ARGC; + napi_value argv[MAX_ARGC] = { nullptr }; + void* data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, &data)); + if (argc < MIN_ARGC || argv[0] == nullptr || argv[1] == nullptr) { + LOG_ERROR("invalid args, argc : %{public}zu.", argc); + return CreateJsUndefined(env); + } + if (data == nullptr) { + LOG_ERROR("invalid object."); + return CreateJsUndefined(env); } DatashareBusinessError businessError; - if ((info->argv[0])->TypeOf() == NATIVE_OBJECT) { + napi_valuetype type = napi_undefined; + napi_typeof(env, argv[0], &type); + if (type == napi_valuetype::napi_object) { LOG_INFO("Error in callback"); - UnWrapBusinessError(reinterpret_cast(engine), reinterpret_cast(info->argv[0]), - businessError); - } - - if (info->functionInfo == nullptr || info->functionInfo->data == nullptr) { - LOG_ERROR("invalid object."); - return engine->CreateUndefined(); + UnWrapBusinessError(env, argv[0], businessError); } - - JsDataShareExtAbility* instance = static_cast(info->functionInfo->data); + JsDataShareExtAbility* instance = static_cast(data); if (instance != nullptr) { instance->SetBlockWaiting(true); instance->SetBusinessError(businessError); - instance->SetAsyncResult(info->argv[1]); - instance->CheckAndSetAsyncResult(engine); + instance->SetAsyncResult(argv[1]); + instance->CheckAndSetAsyncResult(env); } - - return engine->CreateUndefined(); + return CreateJsUndefined(env); } -NativeValue* JsDataShareExtAbility::AsyncCallbackWithContext(NativeEngine* engine, NativeCallbackInfo* info) +napi_value JsDataShareExtAbility::AsyncCallbackWithContext(napi_env env, napi_callback_info info) { - if (engine == nullptr || info == nullptr) { + if (env == nullptr || info == nullptr) { LOG_ERROR("invalid param."); return nullptr; } - if (info->functionInfo == nullptr || info->functionInfo->data == nullptr) { + + void* data = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data); + if (data == nullptr) { LOG_ERROR("invalid object."); - return engine->CreateUndefined(); + return CreateJsUndefined(env); } - AsyncPoint* instance = static_cast(info->functionInfo->data); + AsyncPoint* instance = static_cast(data); if (instance != nullptr) { if (instance->context->isNeedNotify_) { NotifyToDataShareService(); } } - delete instance; - return engine->CreateUndefined(); + return CreateJsUndefined(env); } -NativeValue *JsDataShareExtAbility::CallObjectMethod( - const char *name, NativeValue *argv[], size_t argc, std::shared_ptr asyncContext) +napi_value JsDataShareExtAbility::CallObjectMethod( + const char *name, napi_value const *argv, size_t argc, std::shared_ptr asyncContext) { if (!jsObj_) { LOG_WARN("Not found DataShareExtAbility.js"); @@ -247,16 +241,15 @@ NativeValue *JsDataShareExtAbility::CallObjectMethod( } HandleEscape handleEscape(jsRuntime_); - auto &nativeEngine = jsRuntime_.GetNativeEngine(); - - NativeValue *value = jsObj_->Get(); - NativeObject *obj = ConvertNativeValueTo(value); + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { LOG_ERROR("Failed to get DataShareExtAbility object"); return nullptr; } - NativeValue *method = obj->GetProperty(name); + napi_value method = nullptr; + napi_get_named_property(env, obj, name, &method); if (method == nullptr) { LOG_ERROR("Failed to get '%{public}s' from DataShareExtAbility object", name); return nullptr; @@ -269,9 +262,9 @@ NativeValue *JsDataShareExtAbility::CallObjectMethod( } point->context = asyncContext; size_t count = argc + 1; - NativeValue **args = new (std::nothrow) NativeValue *[count]; + napi_value *args = new (std::nothrow) napi_value [count]; if (args == nullptr) { - LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new NativeValue error."); + LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new NapiValue error."); delete point; return nullptr; } @@ -279,16 +272,20 @@ NativeValue *JsDataShareExtAbility::CallObjectMethod( args[i] = argv[i]; } - args[argc] = nativeEngine.CreateFunction(ASYNC_CALLBACK_NAME.c_str(), ASYNC_CALLBACK_NAME.length(), - JsDataShareExtAbility::AsyncCallbackWithContext, point); - - auto result = handleEscape.Escape(nativeEngine.CallFunction(value, method, args, count)); - delete[] args; + napi_create_function(env, ASYNC_CALLBACK_NAME, CALLBACK_LENGTH, + JsDataShareExtAbility::AsyncCallbackWithContext, point, &args[argc]); + napi_value callResult = nullptr; + napi_call_function(env, obj, method, count, args, &callResult); + auto result = handleEscape.Escape(callResult); + napi_add_finalizer(env, args[argc], point, + [](napi_env env, void* point, void* finalize_hint) { + delete static_cast(point); + }, nullptr, nullptr); + delete []args; return result; } -NativeValue* JsDataShareExtAbility::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc, - bool isAsync) +napi_value JsDataShareExtAbility::CallObjectMethod(const char* name, napi_value const *argv, size_t argc, bool isAsync) { if (!jsObj_) { LOG_WARN("Not found DataShareExtAbility.js"); @@ -296,25 +293,24 @@ NativeValue* JsDataShareExtAbility::CallObjectMethod(const char* name, NativeVal } HandleEscape handleEscape(jsRuntime_); - auto& nativeEngine = jsRuntime_.GetNativeEngine(); - - NativeValue* value = jsObj_->Get(); - NativeObject* obj = ConvertNativeValueTo(value); + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { LOG_ERROR("Failed to get DataShareExtAbility object"); return nullptr; } - NativeValue* method = obj->GetProperty(name); + napi_value method = nullptr; + napi_get_named_property(env, obj, name, &method); if (method == nullptr) { LOG_ERROR("Failed to get '%{public}s' from DataShareExtAbility object", name); return nullptr; } size_t count = argc + 1; - NativeValue **args = new (std::nothrow) NativeValue *[count]; + napi_value *args = new (std::nothrow) napi_value[count]; if (args == nullptr) { - LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new NativeValue error."); + LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new napivalue error."); return nullptr; } for (size_t i = 0; i < argc; i++) { @@ -326,14 +322,20 @@ NativeValue* JsDataShareExtAbility::CallObjectMethod(const char* name, NativeVal callbackResultString_ = ""; callbackResultStringArr_ = {}; callbackResultObject_ = nullptr; - args[argc] = nativeEngine.CreateFunction(ASYNC_CALLBACK_NAME.c_str(), - ASYNC_CALLBACK_NAME.length(), JsDataShareExtAbility::AsyncCallback, this); + napi_create_function(env, ASYNC_CALLBACK_NAME, CALLBACK_LENGTH, + JsDataShareExtAbility::AsyncCallback, this, &args[argc]); } else { args[argc] = nullptr; } SetBlockWaiting(false); - return handleEscape.Escape(nativeEngine.CallFunction(value, method, args, count)); + napi_value remoteNapi = nullptr; + napi_status status = napi_call_function(env, obj, method, count, args, &remoteNapi); + delete []args; + if (status != napi_ok) { + return nullptr; + } + return handleEscape.Escape(remoteNapi); } void JsDataShareExtAbility::GetSrcPath(std::string &srcPath) @@ -361,7 +363,7 @@ std::vector JsDataShareExtAbility::GetFileTypes(const Uri &uri, con { auto ret = DataShareExtAbility::GetFileTypes(uri, mimeTypeFilter); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -381,10 +383,7 @@ std::vector JsDataShareExtAbility::GetFileTypes(const Uri &uri, con napi_close_handle_scope(env, scope); return ret; } - - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativeMimeTypeFilter = reinterpret_cast(napiMimeTypeFilter); - NativeValue* argv[] = {nativeUri, nativeMimeTypeFilter}; + napi_value argv[] = {napiUri, napiMimeTypeFilter}; CallObjectMethod("getFileTypes", argv, 2); napi_close_handle_scope(env, scope); return ret; @@ -394,7 +393,7 @@ int JsDataShareExtAbility::OpenFile(const Uri &uri, const std::string &mode) { auto ret = DataShareExtAbility::OpenFile(uri, mode); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -414,10 +413,7 @@ int JsDataShareExtAbility::OpenFile(const Uri &uri, const std::string &mode) napi_close_handle_scope(env, scope); return ret; } - - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativeMode = reinterpret_cast(napiMode); - NativeValue* argv[] = {nativeUri, nativeMode}; + napi_value argv[] = {napiUri, napiMode}; CallObjectMethod("openFile", argv, 2); napi_close_handle_scope(env, scope); return ret; @@ -427,7 +423,7 @@ int JsDataShareExtAbility::OpenRawFile(const Uri &uri, const std::string &mode) { auto ret = DataShareExtAbility::OpenRawFile(uri, mode); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -447,10 +443,7 @@ int JsDataShareExtAbility::OpenRawFile(const Uri &uri, const std::string &mode) napi_close_handle_scope(env, scope); return ret; } - - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativeMode = reinterpret_cast(napiMode); - NativeValue* argv[] = {nativeUri, nativeMode}; + napi_value argv[] = {napiUri, napiMode}; CallObjectMethod("openRawFile", argv, 2, false); napi_close_handle_scope(env, scope); return ret; @@ -461,7 +454,7 @@ int JsDataShareExtAbility::Insert(const Uri &uri, const DataShareValuesBucket &v int ret = INVALID_VALUE; ret = DataShareExtAbility::Insert(uri, value); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -480,10 +473,7 @@ int JsDataShareExtAbility::Insert(const Uri &uri, const DataShareValuesBucket &v napi_close_handle_scope(env, scope); return ret; } - - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativeValue = reinterpret_cast(napiValue); - NativeValue* argv[] = {nativeUri, nativeValue}; + napi_value argv[] = {napiUri, napiValue}; CallObjectMethod("insert", argv, 2); napi_close_handle_scope(env, scope); return ret; @@ -495,7 +485,7 @@ int JsDataShareExtAbility::Update(const Uri &uri, const DataSharePredicates &pre int ret = INVALID_VALUE; ret = DataShareExtAbility::Update(uri, predicates, value); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -522,10 +512,7 @@ int JsDataShareExtAbility::Update(const Uri &uri, const DataSharePredicates &pre return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativePredicates = reinterpret_cast(napiPredicates); - NativeValue* nativeValue = reinterpret_cast(napiValue); - NativeValue* argv[] = {nativeUri, nativePredicates, nativeValue}; + napi_value argv[] = {napiUri, napiPredicates, napiValue}; CallObjectMethod("update", argv, 3); napi_close_handle_scope(env, scope); return ret; @@ -536,7 +523,7 @@ int JsDataShareExtAbility::Delete(const Uri &uri, const DataSharePredicates &pre int ret = INVALID_VALUE; ret = DataShareExtAbility::Delete(uri, predicates); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -556,9 +543,7 @@ int JsDataShareExtAbility::Delete(const Uri &uri, const DataSharePredicates &pre return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativePredicates = reinterpret_cast(napiPredicates); - NativeValue* argv[] = {nativeUri, nativePredicates}; + napi_value argv[] = {napiUri, napiPredicates}; CallObjectMethod("delete", argv, 2); napi_close_handle_scope(env, scope); return ret; @@ -571,7 +556,7 @@ std::shared_ptr JsDataShareExtAbility::Query(const Uri &uri, ret = DataShareExtAbility::Query(uri, predicates, columns, businessError); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -598,10 +583,7 @@ std::shared_ptr JsDataShareExtAbility::Query(const Uri &uri, return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* nativePredicates = reinterpret_cast(napiPredicates); - NativeValue* nativeColumns = reinterpret_cast(napiColumns); - NativeValue* argv[] = {nativeUri, nativePredicates, nativeColumns}; + napi_value argv[] = {napiUri, napiPredicates, napiColumns}; CallObjectMethod("query", argv, 3); napi_close_handle_scope(env, scope); return std::make_shared(); @@ -611,7 +593,7 @@ std::string JsDataShareExtAbility::GetType(const Uri &uri) { auto ret = DataShareExtAbility::GetType(uri); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -624,8 +606,7 @@ std::string JsDataShareExtAbility::GetType(const Uri &uri) napi_close_handle_scope(env, scope); return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* argv[] = {nativeUri}; + napi_value argv[] = {napiUri}; CallObjectMethod("getType", argv, 1); napi_close_handle_scope(env, scope); return ret; @@ -637,7 +618,7 @@ int JsDataShareExtAbility::BatchInsert(const Uri &uri, const std::vector(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -674,10 +655,7 @@ int JsDataShareExtAbility::BatchInsert(const Uri &uri, const std::vector(napiUri); - NativeValue* nativeValues = reinterpret_cast(napiValues); - NativeValue* argv[] = {nativeUri, nativeValues}; + napi_value argv[] = {napiUri, napiValues}; CallObjectMethod("batchInsert", argv, 2); napi_close_handle_scope(env, scope); return ret; @@ -738,7 +716,7 @@ Uri JsDataShareExtAbility::NormalizeUri(const Uri &uri) { auto ret = DataShareExtAbility::NormalizeUri(uri); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -751,8 +729,7 @@ Uri JsDataShareExtAbility::NormalizeUri(const Uri &uri) napi_close_handle_scope(env, scope); return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* argv[] = {nativeUri}; + napi_value argv[] = {napiUri}; CallObjectMethod("normalizeUri", argv, 1); napi_close_handle_scope(env, scope); return ret; @@ -762,7 +739,7 @@ Uri JsDataShareExtAbility::DenormalizeUri(const Uri &uri) { auto ret = DataShareExtAbility::DenormalizeUri(uri); HandleScope handleScope(jsRuntime_); - napi_env env = reinterpret_cast(&jsRuntime_.GetNativeEngine()); + napi_env env = jsRuntime_.GetNapiEnv(); napi_handle_scope scope = nullptr; napi_open_handle_scope(env, &scope); if (scope == nullptr) { @@ -775,8 +752,7 @@ Uri JsDataShareExtAbility::DenormalizeUri(const Uri &uri) napi_close_handle_scope(env, scope); return ret; } - NativeValue* nativeUri = reinterpret_cast(napiUri); - NativeValue* argv[] = {nativeUri}; + napi_value argv[] = {napiUri}; CallObjectMethod("denormalizeUri", argv, 1); napi_close_handle_scope(env, scope); return ret; diff --git a/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp b/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp index 96c367f3b22fe70d8447f83d7dfdf9806bdb983a..646a7a59b8bc2043838d9a23fbf86eca6e99b105 100644 --- a/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp +++ b/data_share/frameworks/native/provider/src/js_datashare_ext_ability_context.cpp @@ -26,7 +26,6 @@ #include "napi_remote_object.h" #include "napi_common_start_options.h" #include "start_options.h" -#include "native_engine/native_value.h" namespace OHOS { namespace DataShare { @@ -38,7 +37,7 @@ public: : context_(context) {} ~JsDataShareExtAbilityContext() = default; - static void Finalizer(NativeEngine* engine, void* data, void* hint) + static void Finalizer(napi_env env, void* data, void* hint) { LOG_INFO("JsAbilityContext::Finalizer is called"); std::unique_ptr(static_cast(data)); @@ -48,15 +47,13 @@ private: }; } // namespace -NativeValue* CreateJsDataShareExtAbilityContext(NativeEngine& engine, +napi_value CreateJsDataShareExtAbilityContext(napi_env env, std::shared_ptr context) { LOG_INFO("CreateJsDataShareExtAbilityContext begin"); - NativeValue* objValue = CreateJsExtensionContext(engine, context); - NativeObject* object = ConvertNativeValueTo(objValue); - + napi_value objValue = CreateJsExtensionContext(env, context); std::unique_ptr jsContext = std::make_unique(context); - object->SetNativePointer(jsContext.release(), JsDataShareExtAbilityContext::Finalizer, nullptr); + napi_wrap(env, objValue, jsContext.release(), JsDataShareExtAbilityContext::Finalizer, nullptr, nullptr); return objValue; } } // namespace DataShare diff --git a/data_share/interfaces/inner_api/BUILD.gn b/data_share/interfaces/inner_api/BUILD.gn index 41f542f503093f6d6831c01568c6cbb51e11993f..622a54e2c603d9a758c6980e3036559694a4a000 100644 --- a/data_share/interfaces/inner_api/BUILD.gn +++ b/data_share/interfaces/inner_api/BUILD.gn @@ -74,7 +74,6 @@ datashare_consumer_sources = [ datashare_consumer_external_deps = [ "ability_base:want", "ability_base:zuri", - "ability_runtime:ability_context_native", "ability_runtime:app_context", "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", @@ -88,8 +87,10 @@ datashare_consumer_external_deps = [ ] ohos_shared_library("datashare_consumer") { - include_dirs = - [ "//foundation/distributeddatamgr/kv_store/frameworks/common" ] + include_dirs = [ + "${kvstore_base_path}/frameworks/common", + "${kvstore_base_path}/interfaces/innerkits/distributeddata/include", + ] sources = datashare_consumer_sources configs = [ ":ability_config" ] @@ -171,7 +172,10 @@ ohos_shared_library("datashare_ext_ability_module") { } ohos_static_library("datashare_consumer_static") { - include_dirs = [ "${kvstore_base_path}/frameworks/common" ] + include_dirs = [ + "${kvstore_base_path}/frameworks/common", + "${kvstore_base_path}/interfaces/innerkits/distributeddata/include", + ] sources = datashare_consumer_sources configs = [ ":ability_config" ] diff --git a/data_share/interfaces/inner_api/common/BUILD.gn b/data_share/interfaces/inner_api/common/BUILD.gn index c74fc92a9666445c10f3d2d92a79c17f0a98d20f..52cb4316f2119fa4879833ef05a83cfa3178e580 100644 --- a/data_share/interfaces/inner_api/common/BUILD.gn +++ b/data_share/interfaces/inner_api/common/BUILD.gn @@ -61,7 +61,6 @@ datashare_common_sources = [ datashare_common_external_deps = [ "ability_base:zuri", - "ability_runtime:abilitykit_native", "c_utils:utils", "hilog:libhilog", "hisysevent:libhisysevent", diff --git a/data_share/test/native/unittest/mediadatashare_test/include/mediadatashare_unit_test.h b/data_share/test/native/unittest/mediadatashare_test/include/mediadatashare_unit_test.h index 23516691c8bd952cf17ea27e4ad3af0ec4d97303..31b3446722a84a1c61666d9b93f88014234e1986 100644 --- a/data_share/test/native/unittest/mediadatashare_test/include/mediadatashare_unit_test.h +++ b/data_share/test/native/unittest/mediadatashare_test/include/mediadatashare_unit_test.h @@ -40,18 +40,6 @@ public: void TearDown(); bool UrisEqual(std::list uri1, std::list uri2); bool ChangeInfoEqual(const ChangeInfo &changeInfo, const ChangeInfo &expectChangeInfo); - -protected: - static constexpr const char *DATA_SHARE_URI = "datashare:///com.acts.datasharetest"; - static constexpr const char *MEDIALIBRARY_DATA_URI = "datashare:///com.acts.datasharetest"; - static constexpr const char *MEDIALIBRARY_DATA_URI_ERROR = "test:///com.acts.datasharetest"; - static constexpr const char *FILE_DATA_URI = "file://com.acts.datasharetest"; - static constexpr const char *NORMALIZE_URI = "normalize+datashare:///com.acts.datasharetest"; - static constexpr const char *DENORMALIZE_URI = "denormalize+datashare:///com.acts.datasharetest"; - - static std::shared_ptr CreateDataShareHelper(int32_t saId); - - static std::shared_ptr dataShare_; }; class IDataAbilityObserverTest : public AAFwk::DataAbilityObserverStub { diff --git a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp index aa4cf95b3d5b227eae52b8a94c4ec0f19389b668..e96994db8067c1f07a3c19ab06b429e007c24589 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp @@ -28,10 +28,6 @@ namespace DataShare { using namespace testing::ext; using namespace OHOS::Security::AccessToken; constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; -std::string DATA_SHARE_URI = "datashare:///com.acts.errorcodetest"; -std::string SLIENT_ACCESS_URI = "datashare:///com.acts.errorcodetest/entry/DB00/TBL00?Proxy=true"; -std::string TBL_STU_NAME = "name"; -std::string TBL_STU_AGE = "age"; class ErrorCodeTest : public testing::Test { public: @@ -42,11 +38,15 @@ public: protected: static std::shared_ptr CreateDataShareHelper(int32_t saId, std::string uri); - static std::shared_ptr accessHelper_; - static std::shared_ptr dataShareHelper_; + static inline std::string DATA_SHARE_URI = "datashare:///com.acts.errorcodetest"; + static inline std::string SLIENT_ACCESS_URI = "datashare:///com.acts.errorcodetest/entry/DB00/TBL00?Proxy=true"; + std::string TBL_STU_NAME = "name"; + std::string TBL_STU_AGE = "age"; + static std::shared_ptr g_slientAccessHelper; + static std::shared_ptr dataShareHelper; }; -std::shared_ptr ErrorCodeTest::accessHelper_; -std::shared_ptr ErrorCodeTest::dataShareHelper_; +std::shared_ptr ErrorCodeTest::g_slientAccessHelper; +std::shared_ptr ErrorCodeTest::dataShareHelper; std::shared_ptr ErrorCodeTest::CreateDataShareHelper(int32_t saId, std::string uri) { @@ -67,8 +67,8 @@ std::shared_ptr ErrorCodeTest::CreateDataShareHelper void ErrorCodeTest::SetUpTestCase(void) { LOG_INFO("SetUpTestCase invoked"); - dataShareHelper_ = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, DATA_SHARE_URI); - ASSERT_TRUE(dataShareHelper_ != nullptr); + dataShareHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, DATA_SHARE_URI); + ASSERT_TRUE(dataShareHelper != nullptr); int sleepTime = 3; sleep(sleepTime); @@ -108,8 +108,8 @@ void ErrorCodeTest::SetUpTestCase(void) info.userID, info.bundleName, info.instIndex); SetSelfTokenID(testTokenId); - accessHelper_ = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); - ASSERT_TRUE(accessHelper_ != nullptr); + g_slientAccessHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); + ASSERT_TRUE(g_slientAccessHelper != nullptr); LOG_INFO("SetUpTestCase end"); } @@ -117,8 +117,8 @@ void ErrorCodeTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); - accessHelper_ = nullptr; - dataShareHelper_ = nullptr; + g_slientAccessHelper = nullptr; + dataShareHelper = nullptr; } void ErrorCodeTest::SetUp(void) {} @@ -127,7 +127,7 @@ void ErrorCodeTest::TearDown(void) {} HWTEST_F(ErrorCodeTest, ErrorCodeTest_Insert_Test_001, TestSize.Level0) { LOG_INFO("ErrorCodeTest_Insert_Test_001::Start"); - auto helper = accessHelper_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataShareValuesBucket valuesBucket; std::string value = "lisi"; @@ -143,7 +143,7 @@ HWTEST_F(ErrorCodeTest, ErrorCodeTest_Insert_Test_001, TestSize.Level0) HWTEST_F(ErrorCodeTest, ErrorCodeTest_QUERY_Test_001, TestSize.Level0) { LOG_INFO("ErrorCodeTest_QUERY_Test_001::Start"); - auto helper = accessHelper_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataSharePredicates predicates; predicates.EqualTo(TBL_STU_NAME, "lisi"); @@ -170,7 +170,7 @@ HWTEST_F(ErrorCodeTest, ErrorCodeTest_QUERY_Test_001, TestSize.Level0) HWTEST_F(ErrorCodeTest, ErrorCodeTest_QUERY_Test_002, TestSize.Level0) { LOG_INFO("ErrorCodeTest_QUERY_Test_002::Start"); - ASSERT_TRUE(dataShareHelper_ != nullptr); + ASSERT_TRUE(dataShareHelper != nullptr); Uri uri(DATA_SHARE_URI); DataShare::DataShareValuesBucket valuesBucket; @@ -178,21 +178,21 @@ HWTEST_F(ErrorCodeTest, ErrorCodeTest_QUERY_Test_002, TestSize.Level0) valuesBucket.Put(TBL_STU_NAME, value); int age = 30; valuesBucket.Put(TBL_STU_AGE, age); - int retVal = dataShareHelper_->Insert(uri, valuesBucket); + int retVal = dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); DataShare::DataSharePredicates predicates; predicates.EqualTo(TBL_STU_NAME, "wangwu"); vector columns; DatashareBusinessError error; - auto resultSet = dataShareHelper_->Query(uri, predicates, columns, &error); + auto resultSet = dataShareHelper->Query(uri, predicates, columns, &error); EXPECT_EQ(error.GetCode(), 401); EXPECT_EQ(resultSet, nullptr); DataShare::DataSharePredicates deletePredicates; std::string selections = TBL_STU_NAME + " = 'wangwu'"; deletePredicates.SetWhereClause(selections); - retVal = dataShareHelper_->Delete(uri, deletePredicates); + retVal = dataShareHelper->Delete(uri, deletePredicates); EXPECT_EQ((retVal > 0), true); LOG_INFO("ErrorCodeTest_QUERY_Test_002::End"); } diff --git a/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp index dcdaa546822ee0c3501a6663cad0988fab20af06..bc855064327cff2b5bad7a0527170ba93d00bad8 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp @@ -30,7 +30,6 @@ using namespace testing::ext; using namespace OHOS::Security::AccessToken; constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; - class JoinTest : public testing::Test { public: static void SetUpTestCase(void); @@ -47,9 +46,11 @@ protected: static constexpr const char *USER_URI = "datashare:///com.acts.datasharetest/entry/DB00/user?Proxy=true"; static constexpr const char *BOOK_URI = "datashare:///com.acts.datasharetest/entry/DB00/book?Proxy=true"; static std::shared_ptr CreateDataShareHelper(int32_t saId, std::string uri); - static std::shared_ptr clientAccess_; + static std::shared_ptr g_slientAccessHelper; + std::string TBL_STU_NAME = "name"; + std::string TBL_STU_AGE = "age"; }; -std::shared_ptr JoinTest::clientAccess_; +std::shared_ptr JoinTest::g_slientAccessHelper; std::shared_ptr JoinTest::CreateDataShareHelper(int32_t saId, std::string uri) { @@ -106,8 +107,8 @@ void JoinTest::SetUpTestCase(void) info.userID, info.bundleName, info.instIndex); SetSelfTokenID(testTokenId); - clientAccess_ = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); - ASSERT_TRUE(clientAccess_ != nullptr); + g_slientAccessHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); + ASSERT_TRUE(g_slientAccessHelper != nullptr); JoinTest::InsertUserDates(); JoinTest::InsertBookDates(); LOG_INFO("SetUpTestCase end"); @@ -117,7 +118,7 @@ void JoinTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); - clientAccess_ = nullptr; + g_slientAccessHelper = nullptr; } void JoinTest::SetUp(void) {} @@ -134,7 +135,7 @@ void JoinTest::InsertUserDates() values.Put("age", 29); values.Put("balance", 100.51); Uri userUri (USER_URI); - clientAccess_->Insert(userUri, values); + g_slientAccessHelper->Insert(userUri, values); values.Clear(); values.Put("userId", 2); @@ -142,7 +143,7 @@ void JoinTest::InsertUserDates() values.Put("lastName", "Si"); values.Put("age", 30); values.Put("balance", 200.51); - clientAccess_->Insert(userUri, values); + g_slientAccessHelper->Insert(userUri, values); values.Clear(); values.Put("userId", 3); @@ -150,7 +151,7 @@ void JoinTest::InsertUserDates() values.Put("lastName", std::string("Wu")); values.Put("age", 30); values.Put("balance", 300.51); - clientAccess_->Insert(userUri, values); + g_slientAccessHelper->Insert(userUri, values); values.Clear(); values.Put("userId", 4); @@ -158,7 +159,7 @@ void JoinTest::InsertUserDates() values.Put("lastName", "Liu"); values.Put("age", 31); values.Put("balance", 400.51); - clientAccess_->Insert(userUri, values); + g_slientAccessHelper->Insert(userUri, values); values.Clear(); values.Put("userId", 5); @@ -166,7 +167,7 @@ void JoinTest::InsertUserDates() values.Put("lastName", "Qi"); values.Put("age", 32); values.Put("balance", 500.51); - clientAccess_->Insert(userUri, values); + g_slientAccessHelper->Insert(userUri, values); LOG_INFO("JoinTest::InsertUserDates ends"); } @@ -179,19 +180,19 @@ void JoinTest::InsertBookDates() values.Put("name", "SanGuo"); values.Put("userId", 1); Uri bookUri (BOOK_URI); - clientAccess_->Insert(bookUri, values); + g_slientAccessHelper->Insert(bookUri, values); values.Clear(); values.Put("id", 2); values.Put("name", "XiYouJi"); values.Put("userId", 2); - clientAccess_->Insert(bookUri, values); + g_slientAccessHelper->Insert(bookUri, values); values.Clear(); values.Put("id", 3); values.Put("name", "ShuiHuZhuan"); values.Put("userId", 3); - clientAccess_->Insert(bookUri, values); + g_slientAccessHelper->Insert(bookUri, values); LOG_INFO("JoinTest::InsertBookDates end"); } @@ -209,7 +210,7 @@ int JoinTest::ResultSize(std::shared_ptr &resultSet) HWTEST_F(JoinTest, Join_CrossJoin_001, TestSize.Level0) { - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; DataShare::DataSharePredicates predicates; std::vector clauses; clauses.push_back("user.userId = book.userId"); @@ -217,7 +218,7 @@ HWTEST_F(JoinTest, Join_CrossJoin_001, TestSize.Level0) std::vector columns; Uri userUri (USER_URI); - auto resultSet = clientAccess_->Query(userUri, predicates, columns); + auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns); int rowCount; resultSet->GetRowCount(rowCount); EXPECT_EQ(3, rowCount); @@ -258,7 +259,7 @@ HWTEST_F(JoinTest, Join_CrossJoin_001, TestSize.Level0) HWTEST_F(JoinTest, Join_InnerJoin_001, TestSize.Level0) { - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; DataShare::DataSharePredicates predicates; std::vector clauses; clauses.push_back("user.userId = book.userId"); @@ -266,7 +267,7 @@ HWTEST_F(JoinTest, Join_InnerJoin_001, TestSize.Level0) std::vector columns; Uri userUri (USER_URI); - auto resultSet = clientAccess_->Query(userUri, predicates, columns); + auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns); int rowCount; resultSet->GetRowCount(rowCount); @@ -308,7 +309,7 @@ HWTEST_F(JoinTest, Join_InnerJoin_001, TestSize.Level0) HWTEST_F(JoinTest, Join_LeftOuterJoin_001, TestSize.Level0) { - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; DataShare::DataSharePredicates predicates; std::vector fields; fields.push_back("userId"); @@ -316,7 +317,7 @@ HWTEST_F(JoinTest, Join_LeftOuterJoin_001, TestSize.Level0) std::vector columns; Uri userUri (USER_URI); - auto resultSet = clientAccess_->Query(userUri, predicates, columns); + auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns); int rowCount; resultSet->GetRowCount(rowCount); @@ -354,7 +355,7 @@ HWTEST_F(JoinTest, Join_LeftOuterJoin_001, TestSize.Level0) HWTEST_F(JoinTest, Join_LeftOuterJoin_002, TestSize.Level0) { - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; DataShare::DataSharePredicates predicates; std::vector clauses; clauses.push_back("user.userId = book.userId"); @@ -362,7 +363,7 @@ HWTEST_F(JoinTest, Join_LeftOuterJoin_002, TestSize.Level0) std::vector columns; Uri userUri (USER_URI); - auto resultSet = clientAccess_->Query(userUri, predicates, columns); + auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns); int rowCount; resultSet->GetRowCount(rowCount); EXPECT_EQ(5, rowCount); diff --git a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp index 6d109c40a82b734e940fdeef3690657b1c161b34..1f198f6b14a4e02f9812f2c981ce8af0217789e6 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp @@ -31,7 +31,7 @@ namespace OHOS { namespace DataShare { using namespace testing::ext; using namespace OHOS::Security::AccessToken; -std::shared_ptr MediaDataShareUnitTest::dataShare_; + template class ConditionLock { public: @@ -95,9 +95,15 @@ public: }; constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; - - -std::shared_ptr MediaDataShareUnitTest::CreateDataShareHelper(int32_t saId) +std::string DATA_SHARE_URI = "datashare:///com.acts.datasharetest"; +std::string MEDIALIBRARY_DATA_URI = "datashare:///com.acts.datasharetest"; +std::string MEDIALIBRARY_DATA_URI_ERROR = "test:///com.acts.datasharetest"; +std::string FILE_DATA_URI = "file://com.acts.datasharetest"; +std::string NORMALIZE_URI = "normalize+datashare:///com.acts.datasharetest"; +std::string DENORMALIZE_URI = "denormalize+datashare:///com.acts.datasharetest"; +std::shared_ptr g_dataShareHelper; + +std::shared_ptr CreateDataShareHelper(int32_t systemAbilityId) { LOG_INFO("CreateDataShareHelper start"); auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); @@ -105,7 +111,7 @@ std::shared_ptr MediaDataShareUnitTest::CreateDataSh LOG_ERROR("GetSystemAbilityManager get samgr failed."); return nullptr; } - auto remoteObj = saManager->GetSystemAbility(saId); + auto remoteObj = saManager->GetSystemAbility(systemAbilityId); while (remoteObj == nullptr) { LOG_ERROR("GetSystemAbility service failed."); return nullptr; @@ -158,8 +164,8 @@ bool MediaDataShareUnitTest::ChangeInfoEqual(const ChangeInfo &changeInfo, const void MediaDataShareUnitTest::SetUpTestCase(void) { LOG_INFO("SetUpTestCase invoked"); - dataShare_ = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); - ASSERT_TRUE(dataShare_ != nullptr); + g_dataShareHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(g_dataShareHelper != nullptr); int sleepTime = 1; sleep(sleepTime); @@ -170,7 +176,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) valuesBucket.Put("name", "dataShareTest003"); int value1 = 1001; valuesBucket.Put("age", value1); - int retVal = dataShare_->Insert(uri, valuesBucket); + int retVal = g_dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); valuesBucket.Clear(); @@ -179,7 +185,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) valuesBucket.Put("name", "dataShareTest004"); int value2 = 1000; valuesBucket.Put("age", value2); - retVal = dataShare_->Insert(uri, valuesBucket); + retVal = g_dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); valuesBucket.Clear(); @@ -188,7 +194,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) valuesBucket.Put("name", "dataShareTest005"); int value3 = 999; valuesBucket.Put("age", value3); - retVal = dataShare_->Insert(uri, valuesBucket); + retVal = g_dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); LOG_INFO("SetUpTestCase end"); } @@ -196,8 +202,8 @@ void MediaDataShareUnitTest::SetUpTestCase(void) void MediaDataShareUnitTest::TearDownTestCase(void) { LOG_INFO("TearDownTestCase invoked"); - std::shared_ptr helper = dataShare_; - ASSERT_TRUE(dataShare_ != nullptr); + std::shared_ptr helper = g_dataShareHelper; + ASSERT_TRUE(g_dataShareHelper != nullptr); Uri deleteAssetUri(MEDIALIBRARY_DATA_URI); DataShare::DataSharePredicates predicates; predicates.GreaterThan("id", 0); @@ -216,7 +222,7 @@ void MediaDataShareUnitTest::TearDown(void) {} HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataSharePredicates predicates; predicates.EqualTo("name", "dataShareTest003"); @@ -234,7 +240,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_001, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_002, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_002::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.NotEqualTo("name", "dataShareTest003"); vector columns; @@ -251,7 +257,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_002, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_003, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_003::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.Contains("name", "dataShareTest"); vector columns; @@ -268,7 +274,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_003, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_004, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_004::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.BeginsWith("name", "dataShare"); vector columns; @@ -285,7 +291,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_004, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_005, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_005::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.EndsWith("name", "003"); vector columns; @@ -302,7 +308,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_005, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_006, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_006::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.IsNull("name"); vector columns; @@ -319,7 +325,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_006, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_007, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_007::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.IsNotNull("name"); vector columns; @@ -336,7 +342,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_007, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_008, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_008::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.Like("name", "%Test003"); vector columns; @@ -353,7 +359,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_008, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_009, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_009::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.Glob("name", "dataShareTes?003"); vector columns; @@ -370,7 +376,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_009, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_010, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_010::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.Between("age", "0", "999"); vector columns; @@ -387,7 +393,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_010, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_011, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_011::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.NotBetween("age", "0", "999"); vector columns; @@ -404,7 +410,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_011, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_012, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_012::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.GreaterThan("age", 999); vector columns; @@ -421,7 +427,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_012, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_013, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_013::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.LessThan("age", 1000); vector columns; @@ -438,7 +444,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_013, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_014, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_014::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.GreaterThanOrEqualTo("age", 1000); vector columns; @@ -455,7 +461,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_014, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_015, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_015::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.LessThanOrEqualTo("age", 1000); vector columns; @@ -472,7 +478,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_015, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_016, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_016::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.EqualTo("phoneNumber", 20.08) ->BeginWrap() @@ -494,7 +500,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_016, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_017, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_017::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.EqualTo("phoneNumber", 20.08)->And()->EqualTo("name", "dataShareTest004"); vector columns; @@ -511,7 +517,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_017, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_018, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_018::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.OrderByAsc("age"); vector columns; @@ -531,7 +537,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_018, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_019, TestSize.Level0) { LOG_INFO("MediaDataShare_Predicates_Test_019::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.OrderByDesc("phoneNumber"); vector columns; @@ -671,7 +677,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ValueObject_Test_001, TestSize.L HWTEST_F(MediaDataShareUnitTest, MediaDataShare_batchInsert_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_batchInsert_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataShareValuesBucket valuesBucket1; @@ -691,7 +697,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_batchInsert_Test_001, TestSize.L HWTEST_F(MediaDataShareUnitTest, MediaDataShare_NormalizeUri_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_NormalizeUri_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; Uri uri(NORMALIZE_URI); Uri uri_media(MEDIALIBRARY_DATA_URI); auto normalUri = helper->NormalizeUri(uri_media); @@ -702,7 +708,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_NormalizeUri_Test_001, TestSize. HWTEST_F(MediaDataShareUnitTest, MediaDataShare_DenormalizeUri_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_DenormalizeUri_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; Uri uri(DENORMALIZE_URI); Uri uri_media(MEDIALIBRARY_DATA_URI); auto denormalUri = helper->DenormalizeUri(uri_media); @@ -788,7 +794,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_MutliValue_Test_001, TestSize.Le HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_ResultSet_Test_005::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.Contains("name", "dataShareTest"); DataShare::DataShareResultSet resultSet; @@ -821,7 +827,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_001, TestSize.Lev HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_002, TestSize.Level0) { LOG_INFO("MediaDataShare_ResultSet_Test_002::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); DataShare::DataSharePredicates predicates; predicates.EqualTo("name", "dataShareTest003"); @@ -852,7 +858,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_002, TestSize.Lev HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_003, TestSize.Level0) { LOG_INFO("MediaDataShare_ResultSet_Test_003::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); DataShare::DataSharePredicates predicates; predicates.EqualTo("name", "dataShareTest003"); @@ -877,7 +883,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_003, TestSize.Lev HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_004, TestSize.Level0) { LOG_INFO("MediaDataShare_ResultSet_Test_004::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); DataShare::DataSharePredicates predicates; predicates.Contains("name", "dataShareTest"); @@ -925,7 +931,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_005, TestSize.Lev HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_006, TestSize.Level0) { LOG_INFO("MediaDataShare_ResultSet_Test_006::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataShareValuesBucket valuesBucket; @@ -1005,7 +1011,7 @@ HWTEST_F(MediaDataShareUnitTest, Insert_ConnectionNull_Test_001, TestSize.Level0 HWTEST_F(MediaDataShareUnitTest, MediaDataShare_CRUD_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_CRUD_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataShareValuesBucket valuesBucket; @@ -1093,7 +1099,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_NotImplPredicates_Test_001, Test HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Observer_001, TestSize.Level0) { LOG_INFO("MediaDataShare_Observer_001 start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); sptr dataObserver; @@ -1117,7 +1123,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Observer_001, TestSize.Level0) HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ObserverExt_001, TestSize.Level0) { LOG_INFO("MediaDataShare_ObserverExt_001 start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); std::shared_ptr dataObserver = std::make_shared(); @@ -1133,7 +1139,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ObserverExt_001, TestSize.Level0 EXPECT_TRUE(ChangeInfoEqual(dataObserver->changeInfo_, uriChanges)); dataObserver->Clear(); - Uri descendantsUri(std::string(MEDIALIBRARY_DATA_URI) + "/com.ohos.example"); + Uri descendantsUri(MEDIALIBRARY_DATA_URI + "/com.ohos.example"); helper->Insert(descendantsUri, valuesBucket); EXPECT_EQ((retVal > 0), true); ChangeInfo descendantsChanges = { DataShareObserver::ChangeType::INSERT, { descendantsUri } }; @@ -1162,7 +1168,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ObserverExt_001, TestSize.Level0 HWTEST_F(MediaDataShareUnitTest, MediaDataShare_UnregisterObserverExt_001, TestSize.Level0) { LOG_INFO("MediaDataShare_UnregisterObserverExt_001 start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); std::shared_ptr dataObserver = std::make_shared(); @@ -1191,7 +1197,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_UnregisterObserverExt_001, TestS HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ToAbsSharedResultSet_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_ToAbsSharedResultSet_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; DataShare::DataSharePredicates predicates; predicates.EqualTo("name", "dataShareTest003"); vector columns; @@ -1210,7 +1216,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ToAbsSharedResultSet_Test_001, T HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ExecuteBatch_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_ExecuteBatch_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; std::vector statements; DataShare::OperationStatement statement1; @@ -1245,7 +1251,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ExecuteBatch_Test_001, TestSize. HWTEST_F(MediaDataShareUnitTest, MediaDataShare_InsertExt_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_InsertExt_Test_001::Start"); - std::shared_ptr helper = dataShare_; + std::shared_ptr helper = g_dataShareHelper; ASSERT_TRUE(helper != nullptr); Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataShareValuesBucket valuesBucket; diff --git a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp index 885dadc8f9e3adbb105b3f1fe7309e0377bb1733..2edbad7e20f51428f26fb0d4fd7f6a20f5a7daa4 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp @@ -39,12 +39,12 @@ public: protected: static constexpr const char *DATA_SHARE_URI = "datashare:///com.acts.datasharetest"; static constexpr const char *SLIENT_ACCESS_URI = "datashare:///com.acts.datasharetest/entry/DB00/TBL00?Proxy=true"; - static constexpr const char *TBL_STU_NAME = "name"; - static constexpr const char *TBL_STU_AGE = "age"; + std::string TBL_STU_NAME = "name"; + std::string TBL_STU_AGE = "age"; static std::shared_ptr CreateDataShareHelper(int32_t saId, std::string uri); - static std::shared_ptr clientAccess_; + static std::shared_ptr g_slientAccessHelper; }; -std::shared_ptr SlientAccessTest::clientAccess_; +std::shared_ptr SlientAccessTest::g_slientAccessHelper; std::shared_ptr SlientAccessTest::CreateDataShareHelper(int32_t saId, std::string uri) { LOG_INFO("CreateDataShareHelper start"); @@ -105,8 +105,8 @@ void SlientAccessTest::SetUpTestCase(void) info.userID, info.bundleName, info.instIndex); SetSelfTokenID(testTokenId); - clientAccess_ = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); - ASSERT_TRUE(clientAccess_ != nullptr); + g_slientAccessHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI); + ASSERT_TRUE(g_slientAccessHelper != nullptr); LOG_INFO("SetUpTestCase end"); } @@ -114,7 +114,7 @@ void SlientAccessTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); - clientAccess_ = nullptr; + g_slientAccessHelper = nullptr; } void SlientAccessTest::SetUp(void) {} @@ -123,7 +123,7 @@ void SlientAccessTest::TearDown(void) {} HWTEST_F(SlientAccessTest, SlientAccess_Insert_Test_001, TestSize.Level0) { LOG_INFO("SlientAccess_Insert_Test_001::Start"); - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataShareValuesBucket valuesBucket; std::string value = "lisi"; @@ -139,13 +139,13 @@ HWTEST_F(SlientAccessTest, SlientAccess_Insert_Test_001, TestSize.Level0) HWTEST_F(SlientAccessTest, SlientAccess_Update_Test_001, TestSize.Level0) { LOG_INFO("SlientAccess_Update_Test_001::Start"); - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataShareValuesBucket valuesBucket; int value = 50; valuesBucket.Put(TBL_STU_AGE, value); DataShare::DataSharePredicates predicates; - std::string selections = std::string(TBL_STU_NAME) + " = 'lisi'"; + std::string selections = TBL_STU_NAME + " = 'lisi'"; predicates.SetWhereClause(selections); int retVal = helper->Update(uri, predicates, valuesBucket); EXPECT_EQ((retVal > 0), true); @@ -155,7 +155,7 @@ HWTEST_F(SlientAccessTest, SlientAccess_Update_Test_001, TestSize.Level0) HWTEST_F(SlientAccessTest, SlientAccess_Query_Test_001, TestSize.Level0) { LOG_INFO("SlientAccess_Query_Test_001::Start"); - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataSharePredicates predicates; predicates.EqualTo(TBL_STU_NAME, "lisi"); @@ -172,11 +172,11 @@ HWTEST_F(SlientAccessTest, SlientAccess_Query_Test_001, TestSize.Level0) HWTEST_F(SlientAccessTest, SlientAccess_Delete_Test_001, TestSize.Level0) { LOG_INFO("SlientAccess_Delete_Test_001::Start"); - auto helper = clientAccess_; + auto helper = g_slientAccessHelper; Uri uri(SLIENT_ACCESS_URI); DataShare::DataSharePredicates deletePredicates; - std::string selections = std::string(TBL_STU_NAME) + " = 'lisi'"; + std::string selections = TBL_STU_NAME + " = 'lisi'"; deletePredicates.SetWhereClause(selections); int retVal = helper->Delete(uri, deletePredicates); EXPECT_EQ((retVal > 0), true); diff --git a/datamgr_service/BUILD.gn b/datamgr_service/BUILD.gn index 8608ac643ee991019a66a85f2391eb07a9b47a55..71f3ee228b6dc2bbbb2dea9533512794a2d15b60 100644 --- a/datamgr_service/BUILD.gn +++ b/datamgr_service/BUILD.gn @@ -18,7 +18,6 @@ group("build_native_test") { "services/distributeddataservice/adapter/test:unittest", "services/distributeddataservice/app/test:unittest", "services/distributeddataservice/framework/test:unittest", - "services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest:unittest", "services/distributeddataservice/service/test:unittest", ] } diff --git a/datamgr_service/CMakeLists.txt b/datamgr_service/CMakeLists.txt index 32101c8ae798fe5f11abb7fe61a72902f8a13c77..4ff621eb78dce616d092726291e5da04ad3b09e7 100644 --- a/datamgr_service/CMakeLists.txt +++ b/datamgr_service/CMakeLists.txt @@ -1,4 +1,3 @@ cmake_minimum_required(VERSION 3.11.2) project(datamgr_service) add_subdirectory(services/distributeddataservice) -add_subdirectory(services/distributeddataservice/service/data_share/gaussdb_rd) diff --git a/datamgr_service/conf/config.json b/datamgr_service/conf/config.json index cf89a760cce8d5244f042aaa87bb079439377234..2d18724ed4d2ff107c3dc5f8e7760e918e53a6f1 100644 --- a/datamgr_service/conf/config.json +++ b/datamgr_service/conf/config.json @@ -75,6 +75,11 @@ "version": 50331651, "pattern": "/data/{type}/{area}/{userId}/database/{bundleName}/{hapName}/{store}", "metaPath": "/data/service/el1/public/database/distributeddata/meta" + }, + { + "version": 50331653, + "pattern": "/data/{type}/{area}/{userId}/database/{bundleName}/{hapName}/{store}/{customDir}", + "metaPath": "/data/service/el1/public/database/distributeddata/meta" } ] }, diff --git a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn index 7c5cebe19fb10d5e8bf84fe7331ae29a4506b575..88ceb2a79b0e3b987b59bc50a6f7131c88a92ce8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn @@ -40,6 +40,11 @@ config("distributeddata_adapter_public_config") { } ohos_shared_library("distributeddata_adapter") { + sanitize = { + boundary_sanitize = true + integer_overflow = true + ubsan = true + } sources = [] configs = [ ":distributeddata_adapter_private_config" ] diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index 1ac478c1351f18f3bd526ee9a8318f2c7c20f6ae..e143ff1d84618ca8c1582008443a247413193e44 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -98,8 +98,8 @@ private: int32_t NetConnCallbackObserver::NetAvailable(sptr &netHandle) { ZLOGI("OnNetworkAvailable"); - dmAdapter_.Online(dmAdapter_.cloudDmInfo); dmAdapter_.isNetAvailable_ = true; + dmAdapter_.Online(dmAdapter_.cloudDmInfo); return DistributedKv::SUCCESS; } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index 3eac36b33356d82750699b42ba276462f9547111..5f27529d0fa301fc756ddaa371f57932f78560f6 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -218,11 +218,13 @@ std::string SoftBusAdapter::DelConnect(int32_t connId) { lock_guard lock(connMutex_); std::string name; - for (const auto& conn : connects_) { - if (*conn.second == connId) { - name = conn.first; - connects_.erase(conn.first); - break; + for (auto iter = connects_.begin(); iter != connects_.end();) { + if (*iter->second == connId) { + name += iter->first; + name += " "; + connects_.erase(iter++); + } else { + iter++; } } return name; diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn index 9d23ea69a0912a7c7dd7b0d09bc5343deaa280fe..fdf76f351686bad9d82084aefbf807f9d9441f62 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn @@ -36,6 +36,7 @@ ohos_static_library("distributeddata_dfx_static") { "../include/log", "../include/autils", "${kv_store_common_path}", + "${kv_store_path}/interfaces/inner_api/distributeddata/include", "//third_party/openssl/include/", ] @@ -48,6 +49,7 @@ ohos_static_library("distributeddata_dfx_static") { "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", + "kv_store:distributeddata_inner", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/test/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/dfx/test/BUILD.gn index fe26d017b5bbed375bf6bd608a8c277d9fb48bd1..f866b02e53a63f5eafa6d3970a5d63969f6d0983 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/test/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") module_output_path = "datamgr_service/distributeddatafwk" @@ -25,6 +26,7 @@ config("module_dfx_mst_config") { "../../include/log", "../../include/autils", "../../include/dfx", + "${kv_store_path}/interfaces/inner_api/distributeddata/include", "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", "//third_party/openssl/include/", @@ -44,6 +46,7 @@ ohos_unittest("DistributeddataDfxMSTTest") { "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", + "kv_store:distributeddata_inner", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ @@ -102,6 +105,7 @@ ohos_unittest("DistributeddataDfxUTTest") { "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", + "kv_store:distributeddata_inner", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] deps = [ diff --git a/datamgr_service/services/distributeddataservice/app/BUILD.gn b/datamgr_service/services/distributeddataservice/app/BUILD.gn index b703e19e948906e544b8340dc18cfff967d14c7e..bd35fa6a2e71e9e6effca6fd97aec35456c81a63 100644 --- a/datamgr_service/services/distributeddataservice/app/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/BUILD.gn @@ -60,6 +60,7 @@ config("module_private_config") { "../adapter/include/utils", "../adapter/include/dfx", "../adapter/include", + "../service/dumper/include", # for ipc_core interfaces. "include", @@ -76,7 +77,6 @@ config("module_private_config") { ohos_shared_library("distributeddataservice") { sources = [ - "src/dump_helper.cpp", "src/feature_stub_impl.cpp", "src/kvstore_account_observer.cpp", "src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp index a0138ff469ce62e0455cae7bfbd65a368b6ac804..c653d9576b4338d1e1e065d464d03293546bce90 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/checker/system_checker.cpp @@ -53,7 +53,7 @@ std::string SystemChecker::GetAppId(const CheckerManager::StoreInfo &info) bool SystemChecker::IsValid(const CheckerManager::StoreInfo &info) { auto type = AccessTokenKit::GetTokenTypeFlag(info.tokenId); - return (type == TOKEN_NATIVE || type == TOKEN_SHELL || info.uid == CheckerManager::ROOT_UID); + return (type == TOKEN_NATIVE || type == TOKEN_SHELL); } } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/dump_helper.cpp b/datamgr_service/services/distributeddataservice/app/src/dump_helper.cpp deleted file mode 100644 index 0c5f77a566968d39b35383dea67bcd9d0a00dd61..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/app/src/dump_helper.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2022-2022 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 "dump_helper.h" -#include "kvstore_data_service.h" -#include "log_print.h" - -namespace OHOS { -namespace DistributedKv { -namespace { -constexpr int32_t MAX_RECORED_ERROR = 10; -constexpr int32_t SUB_CMD_NAME = 0; -constexpr int32_t SUB_CMD_PARAM = 1; -constexpr int32_t CMD_NO_PARAM = 1; -constexpr int32_t CMD_HAS_PARAM = 2; -constexpr const char *CMD_HELP = "-h"; -constexpr const char *CMD_USER_INFO = "-userInfo"; -constexpr const char *CMD_APP_INFO = "-appInfo"; -constexpr const char *CMD_STORE_INFO = "-storeInfo"; -constexpr const char *CMD_ERROR_INFO = "-errorInfo"; -constexpr const char *ILLEGAL_INFOMATION = "The arguments are illegal and you can enter '-h' for help.\n"; -} - -void DumpHelper::AddDumpOperation(const DumpNoParamFunc &dumpAll, const DumpNoParamFunc &dumpUserInfo, - const DumpWithParamFunc &dumpAppInfo, const DumpWithParamFunc &dumpStoreInfo) -{ - if (dumpAll == nullptr || dumpUserInfo == nullptr || dumpAppInfo == nullptr || dumpStoreInfo == nullptr) { - return; - } - dumpAll_ = dumpAll; - dumpUserInfo_ = dumpUserInfo; - dumpAppInfo_ = dumpAppInfo; - dumpStoreInfo_ = dumpStoreInfo; -} - -void DumpHelper::AddErrorInfo(const std::string &error) -{ - std::lock_guard lock(hidumperMutex_); - if (g_errorInfo.size() + 1 > MAX_RECORED_ERROR) { - g_errorInfo.pop_front(); - g_errorInfo.push_back(error); - } else { - g_errorInfo.push_back(error); - } -} - -void DumpHelper::ShowError(int fd) -{ - dprintf(fd, "The number of recent errors recorded is %zu\n", g_errorInfo.size()); - int i = 0; - for (const auto &it : g_errorInfo) { - dprintf(fd, "Error ID: %d ErrorInfo: %s\n", ++i, it.c_str()); - } -} - -bool DumpHelper::Dump(int fd, const std::vector &args) -{ - std::string command = ""; - std::string param = ""; - - if (args.size() == CMD_NO_PARAM) { - command = args.at(SUB_CMD_NAME); - } else if (args.size() == CMD_HAS_PARAM) { - command = args.at(SUB_CMD_NAME); - param = args.at(SUB_CMD_PARAM); - } else { - ShowError(fd); - if (!dumpAll_) { - return false; - } - dumpAll_(fd); - } - - if (command == CMD_HELP) { - ShowHelp(fd); - } else if (command == CMD_ERROR_INFO) { - ShowError(fd); - } else if (command == CMD_USER_INFO) { - if (!dumpUserInfo_) { - return false; - } - dumpUserInfo_(fd); - } else if (command == CMD_APP_INFO) { - if (!dumpAppInfo_) { - return false; - } - dumpAppInfo_(fd, param); - } else if (command == CMD_STORE_INFO) { - if (!dumpStoreInfo_) { - return false; - } - dumpStoreInfo_(fd, param); - } else { - ShowIllealInfomation(fd); - } - return true; -} - -void DumpHelper::ShowHelp(int fd) -{ - std::string result; - result.append("Usage:dump [options]\n") - .append("Description:\n") - .append(CMD_USER_INFO) - .append(" ") - .append("dump all user information in the system\n") - .append(CMD_APP_INFO) - .append(" ") - .append("dump list of all app information in the system\n") - .append(CMD_APP_INFO) - .append(" [appID] ") - .append("dump information about the specified app in the system\n") - .append(CMD_STORE_INFO) - .append(" ") - .append("dump list of all store information in the system\n") - .append(CMD_STORE_INFO) - .append(" [storeID] ") - .append("dump information about the specified store in the system\n") - .append(CMD_ERROR_INFO) - .append(" ") - .append("dump the recent errors information in the system\n"); - dprintf(fd, "%s\n", result.c_str()); -} - -void DumpHelper::ShowIllealInfomation(int fd) -{ - dprintf(fd, "%s\n", ILLEGAL_INFOMATION); -} -} // namespace DistributedKv -} // namespace OHOS - diff --git a/datamgr_service/services/distributeddataservice/app/src/dump_helper.h b/datamgr_service/services/distributeddataservice/app/src/dump_helper.h deleted file mode 100644 index c5fb314cf366531737ce94604b3ca7b9cc1ba848..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/app/src/dump_helper.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2022-2022 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 DISTRIBUTEDDATA_SERVICE_DUMPE_HELPER_H -#define DISTRIBUTEDDATA_SERVICE_DUMPE_HELPER_H - -#include -#include -#include -#include -#include -#include "store_errno.h" -#include "singleton.h" - -namespace OHOS { -namespace DistributedKv { -class DumpHelper : public Singleton { -public: - using DumpNoParamFunc = std::function; - using DumpWithParamFunc = std::function; - DumpHelper() = default; - virtual ~DumpHelper() = default; - void AddDumpOperation(const DumpNoParamFunc &dumpAll, const DumpNoParamFunc &dumpUserInfo, - const DumpWithParamFunc &dumpAppInfo, const DumpWithParamFunc &dumpStoreInfo); - void AddErrorInfo(const std::string &error); - void ShowError(int fd); - bool Dump(int fd, const std::vector &args); -private: - void ShowHelp(int fd); - void ShowIllealInfomation(int fd); - mutable std::mutex hidumperMutex_; - std::list g_errorInfo; - DumpNoParamFunc dumpAll_; - DumpNoParamFunc dumpUserInfo_; - DumpWithParamFunc dumpAppInfo_; - DumpWithParamFunc dumpStoreInfo_; -}; -} // namespace DistributedKv -} // namespace OHOS -#endif // DISTRIBUTEDDATA_SERVICE_DUMPE_HELPER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp index 23de8bd513e62633f71b88c5782ae1b3f292a2b5..9d70a595c0e4c430681f0c34ea04ccb4f57bbadd 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -30,6 +30,8 @@ #include "crypto_manager.h" #include "device_manager_adapter.h" #include "device_matrix.h" +#include "dump/dump_manager.h" +#include "dump_helper.h" #include "eventcenter/event_center.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" @@ -280,6 +282,18 @@ void KvStoreDataService::OnStart() } } AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); + RegisterStoreInfo(); + Handler handlerStoreInfo = std::bind(&KvStoreDataService::DumpStoreInfo, this, std::placeholders::_1, + std::placeholders::_2); + DumpManager::GetInstance().AddHandler("STORE_INFO", uintptr_t(this), handlerStoreInfo); + RegisterUserInfo(); + Handler handlerUserInfo = std::bind(&KvStoreDataService::DumpUserInfo, this, std::placeholders::_1, + std::placeholders::_2); + DumpManager::GetInstance().AddHandler("USER_INFO", uintptr_t(this), handlerUserInfo); + RegisterBundleInfo(); + Handler handlerBundleInfo = std::bind(&KvStoreDataService::DumpBundleInfo, this, std::placeholders::_1, + std::placeholders::_2); + DumpManager::GetInstance().AddHandler("BUNDLE_INFO", uintptr_t(this), handlerBundleInfo); StartService(); } @@ -314,7 +328,7 @@ void KvStoreDataService::StartService() LoadFeatures(); bool ret = SystemAbility::Publish(this); if (!ret) { - DumpHelper::GetInstance().AddErrorInfo("StartService: Service publish failed."); + DumpHelper::GetInstance().AddErrorInfo(SERVER_UNAVAILABLE, "StartService: Service publish failed."); } // Initialize meta db delegate manager. KvStoreMetaManager::GetInstance().SubscribeMeta(StoreMetaData::GetKey({}), @@ -596,7 +610,7 @@ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) if (meta.user != eventInfo.userId) { continue; } - ZLOGI("bundlname:%s, user:%s", meta.bundleName.c_str(), meta.user.c_str()); + ZLOGI("bundleName:%{public}s, user:%{public}s", meta.bundleName.c_str(), meta.user.c_str()); MetaDataManager::GetInstance().DelMeta(meta.GetKey()); MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey()); MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true); @@ -746,4 +760,288 @@ int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32 } return SUCCESS; } + +void KvStoreDataService::RegisterStoreInfo() +{ + OHOS::DistributedData::DumpManager::Config storeInfoConfig; + storeInfoConfig.fullCmd = "--store-info"; + storeInfoConfig.abbrCmd = "-s"; + storeInfoConfig.dumpName = "STORE_INFO"; + storeInfoConfig.countPrintf = PRINTF_COUNT_2; + storeInfoConfig.infoName = " "; + storeInfoConfig.minParamsNum = 0; + storeInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // Store contains no more than three parameters + storeInfoConfig.parentNode = "BUNDLE_INFO"; + storeInfoConfig.dumpCaption = { "| Display all the store statistics", "| Display the store statistics by " + "StoreID" }; + DumpManager::GetInstance().AddConfig(storeInfoConfig.dumpName, storeInfoConfig); +} + +void KvStoreDataService::DumpStoreInfo(int fd, std::map> ¶ms) +{ + std::vector metas; + std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas)) { + ZLOGE("get full meta failed"); + return; + } + FilterData(metas, params); + PrintfInfo(fd, metas); +} + +void KvStoreDataService::FilterData(std::vector &metas, + std::map> &filterInfo) +{ + for (auto iter = metas.begin(); iter != metas.end();) { + if ((IsExist("USER_INFO", filterInfo, iter->user)) || (IsExist("BUNDLE_INFO", filterInfo, iter->bundleName)) || + (IsExist("STORE_INFO", filterInfo, iter->storeId))) { + iter = metas.erase(iter); + } else { + iter++; + } + } +} + +bool KvStoreDataService::IsExist(const std::string &infoName, + std::map> &filterInfo, std::string &metaParam) +{ + auto info = filterInfo.find(infoName); + if (info != filterInfo.end()) { + if (!info->second.empty()) { + auto it = find(info->second.begin(), info->second.end(), metaParam); + if (it == info->second.end()) { + return true; + } + } + } + return false; +} + +void KvStoreDataService::PrintfInfo(int fd, const std::vector &metas) +{ + std::string info; + int indentation = 0; + if (metas.size() > 1) { + info.append("Stores: ").append(std::to_string(metas.size())).append("\n"); + indentation++; + } + for (auto &data : metas) { + char version[VERSION_WIDTH]; + auto flag = sprintf_s(version, sizeof(version), "0x%08X", data.version); + if (flag < 0) { + ZLOGE("get version failed"); + return; + } + info.append(GetIndentation(indentation)) + .append("--------------------------------------------------------------------------\n") + .append(GetIndentation(indentation)).append("StoreID : ").append(data.storeId).append("\n") + .append(GetIndentation(indentation)).append("UId : ").append(data.user).append("\n") + .append(GetIndentation(indentation)).append("BundleName : ").append(data.bundleName).append("\n") + .append(GetIndentation(indentation)).append("AppID : ").append(data.appId).append("\n") + .append(GetIndentation(indentation)).append("StorePath : ").append(data.dataDir).append("\n") + .append(GetIndentation(indentation)).append("StoreType : ") + .append(std::to_string(data.storeType)).append("\n") + .append(GetIndentation(indentation)).append("encrypt : ") + .append(std::to_string(data.isEncrypt)).append("\n") + .append(GetIndentation(indentation)).append("autoSync : ") + .append(std::to_string(data.isAutoSync)).append("\n") + .append(GetIndentation(indentation)).append("schema : ").append(data.schema).append("\n") + .append(GetIndentation(indentation)).append("securityLevel : ") + .append(std::to_string(data.securityLevel)).append("\n") + .append(GetIndentation(indentation)).append("area : ") + .append(std::to_string(data.area)).append("\n") + .append(GetIndentation(indentation)).append("instanceID : ") + .append(std::to_string(data.instanceId)).append("\n") + .append(GetIndentation(indentation)).append("version : ").append(version).append("\n"); + } + dprintf(fd, "--------------------------------------StoreInfo-------------------------------------\n%s\n", + info.c_str()); +} + +std::string KvStoreDataService::GetIndentation(int size) +{ + std::string indentation; + for (int i = 0; i < size; i++) { + indentation.append(INDENTATION); + } + return indentation; +} + +void KvStoreDataService::RegisterUserInfo() +{ + DumpManager::Config userInfoConfig; + userInfoConfig.fullCmd = "--user-info"; + userInfoConfig.abbrCmd = "-u"; + userInfoConfig.dumpName = "USER_INFO"; + userInfoConfig.countPrintf = PRINTF_COUNT_2; + userInfoConfig.infoName = " "; + userInfoConfig.minParamsNum = 0; + userInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // User contains no more than three parameters + userInfoConfig.childNode = "BUNDLE_INFO"; + userInfoConfig.dumpCaption = { "| Display all the user statistics", "| Display the user statistics by UserId" }; + DumpManager::GetInstance().AddConfig(userInfoConfig.dumpName, userInfoConfig); +} + +void KvStoreDataService::BuildData(std::map &datas, const std::vector &metas) +{ + for (auto &meta : metas) { + auto it = datas.find(meta.user); + if (it == datas.end()) { + UserInfo userInfo; + userInfo.userId = meta.user; + userInfo.bundles.insert(meta.bundleName); + datas[meta.user] = userInfo; + } else { + std::set bundles_ = datas[meta.user].bundles; + auto iter = std::find(bundles_.begin(), bundles_.end(), meta.bundleName); + if (iter == bundles_.end()) { + datas[meta.user].bundles.insert(meta.bundleName); + } + } + } +} + +void KvStoreDataService::PrintfInfo(int fd, const std::map &datas) +{ + std::string info; + int indentation = 0; + if (datas.size() > 1) { + info.append("Users : ").append(std::to_string(datas.size())).append("\n"); + indentation++; + } + + for (auto &data : datas) { + info.append(GetIndentation(indentation)) + .append("------------------------------------------------------------------------------\n") + .append("UID : ") + .append(data.second.userId) + .append("\n"); + info.append(GetIndentation(indentation)) + .append("Bundles : ") + .append(std::to_string(data.second.bundles.size())) + .append("\n"); + indentation++; + info.append("------------------------------------------------------------------------------\n"); + for (auto &bundle : data.second.bundles) { + info.append(GetIndentation(indentation)).append("BundleName : ").append(bundle).append("\n"); + } + indentation--; + } + dprintf(fd, "--------------------------------------UserInfo--------------------------------------\n%s\n", + info.c_str()); +} + +void KvStoreDataService::DumpUserInfo(int fd, std::map> ¶ms) +{ + std::vector metas; + std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas)) { + ZLOGE("get full meta failed"); + return; + } + FilterData(metas, params); + std::map datas; + BuildData(datas, metas); + PrintfInfo(fd, datas); +} + +void KvStoreDataService::RegisterBundleInfo() +{ + DumpManager::Config bundleInfoConfig; + bundleInfoConfig.fullCmd = "--bundle-info"; + bundleInfoConfig.abbrCmd = "-b"; + bundleInfoConfig.dumpName = "BUNDLE_INFO"; + bundleInfoConfig.countPrintf = PRINTF_COUNT_2; + bundleInfoConfig.infoName = " "; + bundleInfoConfig.minParamsNum = 0; + bundleInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // Bundle contains no more than three parameters + bundleInfoConfig.parentNode = "USER_INFO"; + bundleInfoConfig.childNode = "STORE_INFO"; + bundleInfoConfig.dumpCaption = { "| Display all the bundle statistics", "| Display the bundle statistics by " + "BundleName" }; + DumpManager::GetInstance().AddConfig(bundleInfoConfig.dumpName, bundleInfoConfig); +} + +void KvStoreDataService::BuildData(std::map &datas, const std::vector &metas) +{ + for (auto &meta : metas) { + auto it = datas.find(meta.bundleName); + if (it == datas.end()) { + BundleInfo bundleInfo; + bundleInfo.bundleName = meta.bundleName; + bundleInfo.appId = meta.appId; + bundleInfo.type = meta.appType; + bundleInfo.uid = meta.uid; + bundleInfo.tokenId = meta.tokenId; + bundleInfo.userId = meta.user; + std::string storeId = meta.storeId; + storeId.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE); + bundleInfo.storeIDs.insert(storeId); + datas[meta.bundleName] = bundleInfo; + } else { + std::set storeIDs_ = datas[meta.bundleName].storeIDs; + std::string storeId = meta.storeId; + storeId.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE); + auto iter = std::find(storeIDs_.begin(), storeIDs_.end(), storeId); + if (iter == storeIDs_.end()) { + datas[meta.bundleName].storeIDs.insert(storeId); + } + } + } +} + +void KvStoreDataService::PrintfInfo(int fd, const std::map &datas) +{ + std::string info; + int indentation = 0; + if (datas.size() > 1) { + info.append("Bundles: ").append(std::to_string(datas.size())).append("\n"); + indentation++; + } + for (auto &data : datas) { + info.append(GetIndentation(indentation)) + .append("--------------------------------------------------------------------------\n"); + info.append(GetIndentation(indentation)).append("BundleName : ") + .append(data.second.bundleName).append("\n"); + info.append(GetIndentation(indentation)).append("AppID : ") + .append(data.second.appId).append("\n"); + info.append(GetIndentation(indentation)).append("Type : ") + .append(data.second.type).append("\n"); + info.append(GetIndentation(indentation)) + .append("UId : ") + .append(std::to_string(data.second.uid)) + .append("\n"); + info.append(GetIndentation(indentation)) + .append("TokenID : ") + .append(std::to_string(data.second.tokenId)) + .append("\n"); + info.append(GetIndentation(indentation)).append("UserID : ").append(data.second.userId).append("\n"); + info.append(GetIndentation(indentation)) + .append("Stores : ") + .append(std::to_string(data.second.storeIDs.size())) + .append("\n"); + indentation++; + info.append("----------------------------------------------------------------------\n"); + for (auto &store : data.second.storeIDs) { + info.append(GetIndentation(indentation)).append("StoreID : ").append(store).append("\n"); + } + indentation--; + } + dprintf(fd, "-------------------------------------BundleInfo-------------------------------------\n%s\n", + info.c_str()); +} + +void KvStoreDataService::DumpBundleInfo(int fd, std::map> ¶ms) +{ + std::vector metas; + std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas)) { + ZLOGE("get full meta failed"); + return; + } + FilterData(metas, params); + std::map datas; + BuildData(datas, metas); + PrintfInfo(fd, datas); +} } // namespace OHOS::DistributedKv diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h index b67fbd9790ffe37149050d4ea08155cc2566f8d6..7e55c06011f1ff2b551566ee2f356c5fcab06537 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -21,7 +21,6 @@ #include #include "account_delegate.h" -#include "dump_helper.h" #include "feature_stub_impl.h" #include "ikvstore_data_service.h" #include "ithread_pool.h" @@ -40,8 +39,22 @@ namespace OHOS::DistributedKv { class KvStoreAccountObserver; class KvStoreDataService : public SystemAbility, public KvStoreDataServiceStub { DECLARE_SYSTEM_ABILITY(KvStoreDataService); + using Handler = std::function> &)>; public: + struct UserInfo { + std::string userId; + std::set bundles; + }; + struct BundleInfo { + std::string bundleName; + std::string appId; + std::string type; + int32_t uid; + uint32_t tokenId; + std::string userId; + std::set storeIDs; + }; using StoreMetaData = DistributedData::StoreMetaData; // record kvstore meta version for compatible, should update when modify kvstore meta structure. static constexpr uint32_t STORE_VERSION = 0x03000001; @@ -50,6 +63,25 @@ public: explicit KvStoreDataService(int32_t systemAbilityId, bool runOnCreate = false); virtual ~KvStoreDataService(); + void RegisterHandler(const std::string &name, Handler &handler); + void RegisterStoreInfo(); + bool IsExist(const std::string &infoName, std::map> &filterInfo, + std::string &metaParam); + void DumpStoreInfo(int fd, std::map> ¶ms); + void FilterData(std::vector &metas, std::map> ¶ms); + void PrintfInfo(int fd, const std::vector &metas); + std::string GetIndentation(int size); + + void RegisterUserInfo(); + void BuildData(std::map &datas, const std::vector &metas); + void PrintfInfo(int fd, const std::map &datas); + void DumpUserInfo(int fd, std::map> ¶ms); + + void RegisterBundleInfo(); + void BuildData(std::map &datas, const std::vector &metas); + void PrintfInfo(int fd, const std::map &datas); + void DumpBundleInfo(int fd, std::map> ¶ms); + Status RegisterClientDeathObserver(const AppId &appId, sptr observer) override; sptr GetFeatureInterface(const std::string &name) override; @@ -140,6 +172,12 @@ private: ConcurrentMap> features_; std::shared_ptr deviceInnerListener_; std::shared_ptr executors_; + static constexpr int VERSION_WIDTH = 11; + static constexpr const char *INDENTATION = " "; + static constexpr int32_t FORMAT_BLANK_SIZE = 32; + static constexpr char FORMAT_BLANK_SPACE = ' '; + static constexpr int32_t PRINTF_COUNT_2 = 2; + static constexpr int MAXIMUM_PARAMETER_LIMIT = 3; }; } #endif // KVSTORE_DATASERVICE_H diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 867ca9da8d01c9c851e48ec592b9a407800ecae8..9421b4f55c35d203017737e575368a53e231f26f 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -28,7 +28,6 @@ #include "device_manager_adapter.h" #include "device_matrix.h" #include "directory/directory_manager.h" -#include "dump_helper.h" #include "eventcenter/event_center.h" #include "kvstore_data_service.h" #include "log_print.h" diff --git a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn index 42bdfd5c77cdcfcc942d581f50fa06f65fddf8d0..cb7573c62394c2eaeae40b5ab061d190eaafbc09 100644 --- a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn @@ -52,6 +52,7 @@ config("module_private_config") { "../src/flowctrl_manager", "../../service/backup/include", "../../../../interfaces/innerkits/distributeddata", + "../../service/dumper/include", "//third_party/json/single_include", ] @@ -66,7 +67,6 @@ config("module_private_config") { ohos_unittest("KvStoreDataServiceTest") { module_out_path = module_output_path sources = [ - "../src/dump_helper.cpp", "../src/feature_stub_impl.cpp", "../src/kvstore_account_observer.cpp", "../src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn index df08302281133b3c53e5205ed0b298ec52ab2624..a392044db896312ef36fa8687a86faf82b3ab9a4 100644 --- a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn @@ -38,6 +38,7 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "${data_service_path}/app/src/uninstaller", "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", + "${data_service_path}/service/dumper/include", "${data_service_path}/service/kvdb", "${data_service_path}/adapter/include/account", "${data_service_path}/adapter/include/permission", @@ -62,7 +63,6 @@ ohos_fuzztest("DataServiceStubFuzzTest") { ] sources = [ - "${data_service_path}/app/src/dump_helper.cpp", "${data_service_path}/app/src/feature_stub_impl.cpp", "${data_service_path}/app/src/kvstore_account_observer.cpp", "${data_service_path}/app/src/kvstore_data_service.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index 692ed9a8028356e45c317ad3a9ecbb8ba6c1beff..7d106e5ff43e89e8e11f2a87ec033264791ea9d5 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -53,6 +53,7 @@ ohos_shared_library("distributeddatasvcfwk") { "cloud/subscription.cpp", "cloud/sync_event.cpp", "directory/directory_manager.cpp", + "dump/dump_manager.cpp", "eventcenter/event.cpp", "eventcenter/event_center.cpp", "feature/feature_system.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt index 761c336f09b2547d94a0d17acd75ca0e51659d51..ff47e2cd74cf227f059e89950973d64d6cd3b005 100644 --- a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt @@ -12,6 +12,7 @@ set(MOCK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../mock") set(KV_STORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../kv_store") aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/backuprule svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/checker svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dump svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/metadata svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/eventcenter svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/serializable svcFwkSrc) diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp index 5a081255246cc8fe47d45fd6cb6e7645cfe782f9..145efcdf08e4c234569d06c2280bbafe3f3ce526 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp @@ -45,6 +45,11 @@ std::shared_ptr CloudDB::Query(const std::string &table, const VBucket & return nullptr; } +std::shared_ptr CloudDB::Query(GenQuery& query, const VBucket& extend) +{ + return nullptr; +} + int32_t CloudDB::Sync(const Devices &devices, int32_t mode, const GenQuery &query, Async async, int32_t wait) { return E_NOT_SUPPORT; diff --git a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp index a3b0458bf9d2f4442e0fc905b110a9a8d9309894..16b34ce02aff6727fdf08e8148d556e357729253 100644 --- a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp @@ -30,7 +30,7 @@ DirectoryManager::DirectoryManager() : actions_({ { "{security}", &DirectoryManager::GetSecurity }, { "{store}", &DirectoryManager::GetStore }, { "{type}", &DirectoryManager::GetType }, { "{area}", &DirectoryManager::GetArea }, { "{userId}", &DirectoryManager::GetUserId }, { "{bundleName}", &DirectoryManager::GetBundleName }, - { "{hapName}", &DirectoryManager::GetHapName } }) + { "{hapName}", &DirectoryManager::GetHapName }, { "{customDir}", &DirectoryManager::GetCustomDir } }) { } @@ -176,6 +176,11 @@ std::string DirectoryManager::GetHapName(const StoreMetaData &metaData) const return metaData.hapName; } +std::string DirectoryManager::GetCustomDir(const StoreMetaData &metaData) const +{ + return metaData.customDir; +} + std::vector DirectoryManager::Split(const std::string &source, const std::string &pattern) const { std::vector values; diff --git a/datamgr_service/services/distributeddataservice/framework/dump/dump_manager.cpp b/datamgr_service/services/distributeddataservice/framework/dump/dump_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4456e83655a3d6279ba5125233516fcd784491cf --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/dump/dump_manager.cpp @@ -0,0 +1,82 @@ +/* +* 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 "dump/dump_manager.h" +namespace OHOS { +namespace DistributedData { +DumpManager &DumpManager::GetInstance() +{ + static DumpManager instance; + return instance; +} + +void DumpManager::AddConfig(const std::string &name, Config &config) +{ + factory_.Insert(name, config); + indexTable_.Insert(config.fullCmd, name); + indexTable_.Insert(config.abbrCmd, name); +} + +DumpManager::Config DumpManager::GetConfig(const std::string &name) +{ + auto it = factory_.Find(name); + if (it.first) { + return (it.second); + } + auto itIndex = indexTable_.Find(name); + if (itIndex.first) { + return GetConfig(itIndex.second); + } + return {}; +} + +ConcurrentMap DumpManager::LoadConfig() +{ + return factory_; +} + +void DumpManager::AddHandler(const std::string &infoName, uintptr_t ptr, const Handler &handler) +{ + handlers_.Compute(infoName, [ptr, &handler](const auto &key, auto &value) { + value.emplace(ptr, handler); + return true; + }); +} + +std::vector DumpManager::GetHandler(const std::string &infoName) +{ + auto it = handlers_.Find(infoName); + std::vector handlers; + if (it.first) { + for (auto &handler : it.second) { + handlers.emplace_back(handler.second); + } + return handlers; + } + auto itIndex = indexTable_.Find(infoName); + if (itIndex.first) { + return GetHandler(itIndex.second); + } + return handlers; +} + +void DumpManager::RemoveHandler(const std::string &infoName, uintptr_t ptr) +{ + handlers_.ComputeIfPresent(infoName, [ptr](const auto &key, auto &value) { + value.erase(ptr); + return !value.empty(); + }); +} +} // namespace DistributedData +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h b/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h index 4f7074c07a1cbd73b0412d72f01052b07e88d5c3..95b4022799e862849049197c1b2fc935980f87f2 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/checker/checker_manager.h @@ -22,7 +22,6 @@ namespace OHOS { namespace DistributedData { class CheckerManager { public: - static constexpr pid_t ROOT_UID = 0; struct Trust { std::string bundleName; std::string appId; diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h index 1b6f246218ac61fb2e24d41ef4798df011b71d1e..1853a729101eaa2ef354570810e628f3572f0bc1 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h @@ -42,6 +42,8 @@ public: virtual std::shared_ptr Query(const std::string &table, const VBucket &extend); + virtual std::shared_ptr Query(GenQuery &query, const VBucket &extend); + virtual int32_t Sync(const Devices &devices, int32_t mode, const GenQuery &query, Async async, int32_t wait); virtual int32_t Watch(int32_t origin, Watcher &watcher); diff --git a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h index ccf9ebd2c6ff33aa8989e9e0d8bcfcfc79880f0f..bdbf46d1c465ef3ad26918e885299b5811e4d46d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h @@ -58,6 +58,7 @@ private: std::string GetUserId(const StoreMetaData &metaData) const; std::string GetBundleName(const StoreMetaData &metaData) const; std::string GetHapName(const StoreMetaData &metaData) const; + std::string GetCustomDir(const StoreMetaData &metaData) const; std::vector Split(const std::string &source, const std::string &pattern) const; int32_t GetVersionIndex(uint32_t version) const; std::string GenPath(const StoreMetaData &metaData, uint32_t version, const std::string &exPath = "") const; diff --git a/datamgr_service/services/distributeddataservice/framework/include/dump/dump_manager.h b/datamgr_service/services/distributeddataservice/framework/include/dump/dump_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..eafa51280e1ec1d3bba662f510606cf32bbf867b --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/dump/dump_manager.h @@ -0,0 +1,66 @@ +/* +* 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 OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_DUMPMANAGER_DUMP_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_DUMPMANAGER_DUMP_MANAGER_H +#include +#include +#include +#include +#include + +#include "concurrent_map.h" +#include "visibility.h" +namespace OHOS { +namespace DistributedData { +class DumpManager { + using Handler = std::function> &)>; + +public: + struct Config { + std::string dumpName; + std::string fullCmd; + std::string abbrCmd; + int countPrintf = 1; + std::string infoName; + int minParamsNum = 0; + int maxParamsNum = 0; + std::string parentNode; + std::string childNode; + std::vector dumpCaption; + bool IsVoid() + { + if (fullCmd.empty()) { + return true; + } + return false; + } + }; + API_EXPORT static DumpManager &GetInstance(); + API_EXPORT void AddConfig(const std::string &name, Config &config); + API_EXPORT Config GetConfig(const std::string &name); + API_EXPORT ConcurrentMap LoadConfig(); + API_EXPORT void AddHandler(const std::string &infoName, uintptr_t ptr, const Handler &handler); + API_EXPORT std::vector GetHandler(const std::string &infoName); + API_EXPORT void RemoveHandler(const std::string &infoName, uintptr_t ptr); + +private: + ConcurrentMap factory_; + ConcurrentMap indexTable_; + ConcurrentMap> handlers_; +}; +} // namespace DistributedData +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_DUMPMANAGER_DUMP_MANAGER_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index e40965fd6e535787c6bef8910cfdb1326d2572f6..e9923b631e727b1e92b92be18cf9228664df37bf 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -22,7 +22,7 @@ namespace OHOS::DistributedData { struct API_EXPORT StoreMetaData final : public Serializable { // record meta version for compatible, should update when modify store meta data structure. - static constexpr uint32_t CURRENT_VERSION = 0x03000004; + static constexpr uint32_t CURRENT_VERSION = 0x03000005; // UID -> uid, deviceAccountId -> userId, userId -> user static constexpr uint32_t FIELD_CHANGED_TAG = 0x03000003; static constexpr uint32_t UUID_CHANGED_TAG = 0x03000004; @@ -42,6 +42,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { std::string bundleName = ""; std::string hapName = ""; std::string dataDir = ""; + std::string customDir = ""; std::string deviceId = ""; std::string schema = ""; std::string storeId = ""; diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h index 7bb8b4493093223a442059240760d66ef78d3e4c..7967fe87d0aeafe9aae2f1fe7a36eba54a10cfaa 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H +#include #include #include #include @@ -32,6 +33,7 @@ class AutoCache { public: using Error = GeneralError; using Store = std::shared_ptr; + using Stores = std::list>; using Watcher = GeneralWatcher; using Watchers = std::set>; using Time = std::chrono::steady_clock::time_point; @@ -46,6 +48,8 @@ public: API_EXPORT Store GetStore(const StoreMetaData &meta, const Watchers &watchers); + API_EXPORT Stores GetStoresIfPresent(uint32_t tokenId, const std::string &storeName = ""); + API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); API_EXPORT void CloseStore(uint32_t tokenId); diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h index c39a328b4fd4f5395d7ace0c98805ee44d87d6c9..36587dff2a20c9557983ff01ecfe29b99d647899 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -43,6 +43,10 @@ public: CLOUD_END, MODE_BUTT = CLOUD_END, }; + enum HighMode { + MANUAL_SYNC_MODE = 0x00000, + AUTO_SYNC_MODE = 0x10000, + }; enum CleanMode { NEARBY_DATA = 0, CLOUD_DATA, @@ -51,6 +55,21 @@ public: CLEAN_MODE_BUTT }; + static inline int32_t MixMode(int32_t syncMode, int32_t highMode) + { + return syncMode | highMode; + } + + static inline int32_t GetSyncMode(int32_t mixMode) + { + return mixMode & 0xFFFF; + } + + static inline int32_t GetHighMode(int32_t mixMode) + { + return mixMode & ~0xFFFF; + } + struct BindInfo { BindInfo(std::shared_ptr db = nullptr, std::shared_ptr loader = nullptr) : db_(std::move(db)), loader_(std::move(loader)) @@ -87,6 +106,10 @@ public: virtual int32_t Unwatch(int32_t origin, Watcher &watcher) = 0; + virtual int32_t RegisterDetailProgressObserver(DetailAsync async) = 0; + + virtual int32_t UnregisterDetailProgressObserver() = 0; + virtual int32_t Close() = 0; virtual int32_t AddRef() = 0; diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h index 4bf696fe7860d1a056e5b86ecb6ae0352697aace..c9c60cb8d1db1e74bdf98cfb04723852e7ca752e 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h @@ -74,11 +74,45 @@ struct Asset { std::string hash; std::string path; }; +using Assets = std::vector; +using Bytes = std::vector; +using Value = std::variant; +using Values = std::vector; +using VBucket = std::map; +using VBuckets = std::vector; +using GenDetails = std::map; +using GenAsync = std::function; +template +inline constexpr size_t TYPE_INDEX = Traits::variant_index_of_v; + +inline constexpr size_t TYPE_MAX = Traits::variant_size_of_v; + +enum class QueryOperation : uint32_t { + ILLEGAL = 0, + IN = 1, + OR = 0x101, + AND, + EQUAL_TO = 0x201, + BEGIN_GROUP = 0x301, + END_GROUP +}; + +struct QueryNode { + QueryOperation op = QueryOperation::ILLEGAL; + std::string fieldName; + std::vector fieldValue; +}; +using QueryNodes = std::vector; struct GenQuery { virtual ~GenQuery() = default; virtual bool IsEqual(uint64_t tid) = 0; virtual std::vector GetTables() = 0; + virtual void SetQueryNodes(const std::string& tableName, QueryNodes&& nodes) {}; + virtual QueryNodes GetQueryNodes(const std::string& tableName) + { + return {}; + }; template int32_t QueryInterface(T *&query) @@ -91,19 +125,6 @@ struct GenQuery { }; }; -using Assets = std::vector; -using Bytes = std::vector; -using Value = std::variant; -using Values = std::vector; -using VBucket = std::map; -using VBuckets = std::vector; -using GenDetails = std::map; -using GenAsync = std::function; -template -inline constexpr size_t TYPE_INDEX = Traits::variant_index_of_v; - -inline constexpr size_t TYPE_MAX = Traits::variant_size_of_v; - template bool GetItem(T &&input, O &output) { diff --git a/datamgr_service/services/distributeddataservice/framework/include/utils/crypto.h b/datamgr_service/services/distributeddataservice/framework/include/utils/crypto.h index e0644a75850813d13f7cf4ef728b82a9e5f34624..7ee1745cc470fc795f96a604901bbdd908453f2b 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/utils/crypto.h +++ b/datamgr_service/services/distributeddataservice/framework/include/utils/crypto.h @@ -17,6 +17,7 @@ #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_UTILS_CRYPTO_H #include #include +#include #include "visibility.h" namespace OHOS { namespace DistributedData { @@ -24,7 +25,8 @@ class Crypto { public: API_EXPORT static std::string Sha256(const std::string &text, bool isUpper = false); API_EXPORT static std::string Sha256(const void *data, size_t size, bool isUpper = false); - API_EXPORT static std::vector Random(int32_t len); + API_EXPORT static std::vector Random(int32_t len, int32_t minimum = 0, + int32_t maximum = std::numeric_limits::max()); }; } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp index 09bcd61e7f7dc153338bd9a95274c81409387530..d2a8f002138e2f1e6f4a4b6165571b1dd1833c16 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -54,6 +54,7 @@ bool StoreMetaData::Marshal(json &node) const SetValue(node[GET_NAME(deviceAccountID)], user); SetValue(node[GET_NAME(userId)], account); SetValue(node[GET_NAME(UID)], uid); + SetValue(node[GET_NAME(customDir)], customDir); return true; } @@ -89,6 +90,7 @@ bool StoreMetaData::Unmarshal(const json &node) GetValue(node, GET_NAME(deviceAccountID), user); GetValue(node, GET_NAME(userId), account); } + GetValue(node, GET_NAME(customDir), customDir); return true; } diff --git a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp index acc206e4c3065de535de06e9c16afc5827a86e93..b4f8647c6096bfd3a86f16641f27f4759ce9e436 100644 --- a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp @@ -83,6 +83,25 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & return store; } +AutoCache::Stores AutoCache::GetStoresIfPresent(uint32_t tokenId, const std::string& storeName) +{ + Stores stores; + stores_.ComputeIfPresent(tokenId, [&stores, &storeName](auto&, std::map& delegates) -> bool { + if (storeName.empty()) { + for (auto& [_, delegate] : delegates) { + stores.push_back(delegate); + } + } else { + auto it = delegates.find(storeName); + if (it != delegates.end()) { + stores.push_back(it->second); + } + } + return !stores.empty(); + }); + return stores; +} + // Should be used within stores_'s thread safe methods void AutoCache::StartTimer() { diff --git a/datamgr_service/services/distributeddataservice/framework/utils/crypto.cpp b/datamgr_service/services/distributeddataservice/framework/utils/crypto.cpp index e553814390387a5c8a6e595550cfd529b54b36d1..e0cef721c83956a0e8a6ce9e945b2e3a8cca5d6e 100644 --- a/datamgr_service/services/distributeddataservice/framework/utils/crypto.cpp +++ b/datamgr_service/services/distributeddataservice/framework/utils/crypto.cpp @@ -22,10 +22,10 @@ std::string Crypto::Sha256(const std::string &text, bool isUpper) return Sha256(text.data(), text.size(), isUpper); } -std::vector Crypto::Random(int32_t len) +std::vector Crypto::Random(int32_t len, int32_t minimum, int32_t maximum) { std::random_device randomDevice; - std::uniform_int_distribution distribution(0, std::numeric_limits::max()); + std::uniform_int_distribution distribution(minimum, maximum); std::vector key(len); for (int32_t i = 0; i < len; i++) { key[i] = static_cast(distribution(randomDevice)); diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index 023498d587e37a784c33a80efcc81a7649d0325a..656c16a7d7770dceaf40e283b4b7460b7a0c7c1f 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -29,6 +29,7 @@ config("module_public_config") { "cloud", "config/include", "crypto/include", + "dumper/include", "kvdb", "matrix/include", "object", @@ -72,6 +73,7 @@ ohos_shared_library("distributeddatasvc") { "config/src/model/network_config.cpp", "config/src/model/protocol_config.cpp", "crypto/src/crypto_manager.cpp", + "dumper/src/dump_helper.cpp", "kvdb/auth_delegate.cpp", "kvdb/kvdb_exporter.cpp", "kvdb/kvdb_service_impl.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt index bc774ddebc41a77b4b8167a0d4d42efc1703161f..db7a56c1dde0fd039ade297e8a8102346e44416a 100644 --- a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt @@ -29,6 +29,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies/general s aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/data_share/subscriber_managers serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/data_share serviceSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dumper/src serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/udmf/lifecycle serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/udmf/permission serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/udmf/preprocess serviceSrc) @@ -36,7 +37,6 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/udmf/store serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/udmf serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/permission/src serviceSrc) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backup/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/config/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/crypto/include) @@ -49,8 +49,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies/data_proxy include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies/data_share) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies/general) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/strategies) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/gaussdb_rd/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data_share/subscriber_managers) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/dumper/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/udmf/lifecycle) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/udmf/permission) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/udmf/preprocess) @@ -76,3 +76,4 @@ target_include_directories(service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kvdb) target_include_directories(service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/rdb) target_include_directories(service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/udmf) target_include_directories(service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/data_share) +target_include_directories(service PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/dumper/include) diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index 461d4186026c15d85a4e24558d55254f95a289c0..5ec0c5b94ef44dffbf9155150fc63552f7250f60 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -110,8 +110,8 @@ std::shared_ptr SyncManager::SyncInfo::GenerateQuery(const std::string private: std::vector tables_; }; - auto &syncTables = tables_[store]; - return std::make_shared(syncTables.empty() ? tables : syncTables); + auto it = tables_.find(store); + return std::make_shared(it == tables_.end() || it->second.empty() ? tables : it->second); } bool SyncManager::SyncInfo::Contains(const std::string& storeName) @@ -201,6 +201,9 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount Defer defer(GetSyncHandler(std::move(retryer)), CloudEvent::CLOUD_SYNC); for (auto &schema : schemas) { + if (!cloud.IsOn(schema.bundleName)) { + continue; + } for (const auto &database : schema.databases) { if (!info.Contains(database.name)) { continue; diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h index d31fa28621f22659ed40d8b172ab97efcec74cf5..67ae2e149af2bb57c5139f4f05e238c4fbee1a32 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h @@ -53,7 +53,7 @@ public: private: friend SyncManager; uint64_t syncId_ = 0; - int32_t mode_ = GenStore::CLOUD_TIME_FIRST; + int32_t mode_ = GenStore::MixMode(GenStore::CLOUD_TIME_FIRST, GenStore::AUTO_SYNC_MODE); int32_t user_ = 0; int32_t wait_ = 0; std::string id_ = DEFAULT_ID; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn index 705e41f242f653144b97a27cf09fbfc805c5837a..2b63b4544f041a6ea2210fe7609489fcc2dc38c6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//build/ohos_var.gni") import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") -import("datamgr_service_data_share.gni") config("module_public_config") { visibility = [ ":*" ] include_dirs = [ @@ -28,6 +27,7 @@ config("module_public_config") { "${datashare_path}/frameworks/native/common/include", "${datashare_path}/interfaces/inner_api/common/include", "${datashare_path}/interfaces/inner_api/consumer/include", + "../crypto/include", ] } group("build_module") { @@ -84,10 +84,10 @@ ohos_shared_library("data_share_service") { configs = [ ":module_public_config" ] deps = [ - "${gaussrd_path}:gaussdb_rd", "../../adapter:distributeddata_adapter", "../../adapter/utils:distributeddata_utils_static", "../../framework:distributeddatasvcfwk", + "../../service:distributeddatasvc", ] external_deps = [ @@ -105,6 +105,7 @@ ohos_shared_library("data_share_service") { "device_manager:devicemanagersdk", "hilog:libhilog", "ipc:ipc_core", + "kv_store:distributeddb", "relational_store:native_rdb", "relational_store:rdb_bms_adapter", "relational_store:rdb_data_share_adapter", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/context.h b/datamgr_service/services/distributeddataservice/service/data_share/common/context.h index 59b2e9a197feebf28f2ed799bd153a9e80986eb3..a99d82c242c8277aaeee7c90204f2927a17c48b9 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/context.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/context.h @@ -45,11 +45,13 @@ public: std::string calledStoreName; std::string calledTableName; std::string calledSourceDir; // the dir of db + std::string secretMetaKey; int version = -1; int errCode = -1; bool isRead = false; bool isAllowCrossPer = false; // can cross permission check, for special SA bool needAutoLoadCallerBundleName = false; + bool isEncryptDb = false; AccessSystemMode accessSystemMode = AccessSystemMode::UNDEFINED; OHOS::AppExecFwk::BundleInfo bundleInfo; std::string type = "rdb"; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 5cf07278a5753b048b3c8e814f705a08705657a5..2e9127b9081bd190a00ed94f19184acb19bdd06c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "DBAdaptor" #include "db_delegate.h" @@ -19,9 +20,10 @@ #include "log_print.h" #include "rdb_delegate.h" namespace OHOS::DataShare { -std::shared_ptr DBDelegate::Create(const std::string &dir, int version, bool registerFunction) +std::shared_ptr DBDelegate::Create(const std::string &dir, int version, bool registerFunction, + bool isEncrypt, const std::string &secretMetaKey) { - return std::make_shared(dir, version, registerFunction); + return std::make_shared(dir, version, registerFunction, isEncrypt, secretMetaKey); } std::shared_ptr KvDBDelegate::GetInstance( diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h index 373521d6e51cb79569f83799a7e85427eaa171b5..269ea77017e771f840a79960cd6a4bf5d112623d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -30,7 +30,8 @@ namespace OHOS::DataShare { class DBDelegate { public: - static std::shared_ptr Create(const std::string &dir, int version, bool registerFunction = true); + static std::shared_ptr Create(const std::string &dir, int version, bool registerFunction = true, + bool isEncrypt = false, const std::string &secretMetaKey = ""); virtual int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index 308d17f4d27cace9ceb9c778b4cf51e0e4dddd79..6d55215a31995fba0d2ea4e859b9d97370c21a01 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -15,6 +15,11 @@ #define LOG_TAG "RdbAdaptor" #include "rdb_delegate.h" +#include "crypto_manager.h" +#include "device_manager_adapter.h" +#include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data.h" +#include "metadata/secret_key_meta_data.h" #include "resultset_json_formatter.h" #include "log_print.h" #include "rdb_utils.h" @@ -50,10 +55,19 @@ std::string RemindTimerFunc(const std::vector &args) return args[ARG_TIME]; } -RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunction) +RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunction, + bool isEncrypt, const std::string &secretMetaKey) { RdbStoreConfig config(dir); config.SetCreateNecessary(false); + if (isEncrypt) { + DistributedData::SecretKeyMetaData secretKeyMeta; + DistributedData::MetaDataManager::GetInstance().LoadMeta(secretMetaKey, secretKeyMeta, true); + std::vector decryptKey; + DistributedData::CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); + config.SetEncryptKey(decryptKey); + std::fill(decryptKey.begin(), decryptKey.end(), 0); + } if (registerFunction) { config.SetScalarFunction("remindTimer", ARGS_SIZE, RemindTimerFunc); } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h index 02093dce577d19fabb3b94d4373e542534d6f1be..6b323927be8a8f2411e58557c59c2a19316fc105 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,7 +31,8 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const std::string &dir, int version, bool registerFunction); + explicit RdbDelegate(const std::string &dir, int version, bool registerFunction, + bool isEncrypt, const std::string &secretMetaKey); int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 973ed64e07ca2694965a371c0e2f34445984c2f0..861f878507f1a4cb7088f22fa165a2312448ee9b 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -26,6 +26,7 @@ #include "datashare_errno.h" #include "datashare_template.h" #include "directory/directory_manager.h" +#include "dump/dump_manager.h" #include "hap_token_info.h" #include "ipc_skeleton.h" #include "log_print.h" @@ -37,6 +38,7 @@ namespace OHOS::DataShare { using FeatureSystem = DistributedData::FeatureSystem; +using DumpManager = OHOS::DistributedData::DumpManager; __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_; DataShareServiceImpl::Factory::Factory() { @@ -512,4 +514,41 @@ DataShareServiceImpl::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSu : CommonEventSubscriber(subscriberInfo) { } + +void DataShareServiceImpl::RegisterDataShareServiceInfo() +{ + DumpManager::Config serviceInfoConfig; + serviceInfoConfig.fullCmd = "--feature-info"; + serviceInfoConfig.abbrCmd = "-f"; + serviceInfoConfig.dumpName = "FEATURE_INFO"; + serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; + DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); +} + +void DataShareServiceImpl::RegisterHandler() +{ + Handler handler = + std::bind(&DataShareServiceImpl::DumpDataShareServiceInfo, this, std::placeholders::_1, std::placeholders::_2); + DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); +} + +void DataShareServiceImpl::DumpDataShareServiceInfo(int fd, std::map> ¶ms) +{ + (void)params; + std::string info; + dprintf(fd, "-------------------------------------DataShareServiceInfo------------------------------\n%s\n", + info.c_str()); +} + +int32_t DataShareServiceImpl::OnInitialize() +{ + RegisterDataShareServiceInfo(); + RegisterHandler(); + return 0; +} + +DataShareServiceImpl::~DataShareServiceImpl() +{ + DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); +} } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h index a505f915877b496d6a6fc246f62db6c4daf52a45..8ce893239fadf1e987a68868f3a610d808e0bc38 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -40,7 +40,9 @@ namespace OHOS::DataShare { class API_EXPORT DataShareServiceImpl : public DataShareServiceStub { public: + using Handler = std::function> &)>; DataShareServiceImpl() = default; + virtual ~DataShareServiceImpl(); int32_t Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) override; int32_t Update(const std::string &uri, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; @@ -71,6 +73,8 @@ public: int32_t OnBind(const BindInfo &binderInfo) override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) override; void NotifyObserver(const std::string &uri) override; + void DumpDataShareServiceInfo(int fd, std::map> ¶ms); + int32_t OnInitialize() override; private: using StaticActs = DistributedData::StaticActs; @@ -93,6 +97,8 @@ private: virtual ~TimerReceiver() = default; virtual void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; }; + void RegisterDataShareServiceInfo(); + void RegisterHandler(); bool SubscribeTimeChanged(); bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni b/datamgr_service/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni deleted file mode 100644 index 5ac6d6289812f2812a4b223fd0b3fe236965ab11..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/service/data_share/datamgr_service_data_share.gni +++ /dev/null @@ -1,23 +0,0 @@ -# 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. - -declare_args() { - gaussrd_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd" - if (defined(global_parts_info) && - defined(global_parts_info.distributeddatamgr_kv_store_lite)) { - gaussrd_path = "//foundation/distributeddatamgr/kv_store_lite/gaussdb_rd" - gaussrd_enchance = true - } else { - gaussrd_enchance = false - } -} diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/README.md b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/README.md deleted file mode 100644 index c2950de99c22cd251865ca9ab2b502671362864c..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/README.md +++ /dev/null @@ -1 +0,0 @@ -# Gauss DB RD diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp index 8d0ce62424e9b6b7b06042906f6be7d3d2741493..3426c041b3a0496f4c086ba3dbc73aea3c894dd6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp @@ -37,7 +37,8 @@ int64_t DeleteStrategy::Execute(std::shared_ptr context, const DataShar ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } - auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version, true, + context->isEncryptDb, context->secretMetaKey); if (delegate == nullptr) { ZLOGE("Create fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); return -1; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp index bdf75cf71bfc9117ebd2680a7f3dd3fa180409f7..d8e2c9bdd1dc14b477191811e6ac1d2d0f849ca6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp @@ -62,6 +62,10 @@ bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr conte } } context->calledSourceDir = metaData.dataDir; + context->isEncryptDb = metaData.isEncrypt; + if (context->isEncryptDb) { + context->secretMetaKey = metaData.GetSecretKey(); + } return true; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp index 3684bce5024516d39c82fa80252d5c35a73fb028..1e5f02c86bb416a15125eb04946bfe1766b1a98a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp @@ -37,7 +37,8 @@ int64_t InsertStrategy::Execute(std::shared_ptr context, const DataShar ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } - auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version, true, + context->isEncryptDb, context->secretMetaKey); if (delegate == nullptr) { ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); return -1; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp index fc86a74840370fc463602820041f228e4ae50402..8fa44e39c7bdbbc167dbeabf3f93410ad1a361bc 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp @@ -40,7 +40,8 @@ std::shared_ptr QueryStrategy::Execute( ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return nullptr; } - auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version, true, + context->isEncryptDb, context->secretMetaKey); if (delegate == nullptr) { ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); return nullptr; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp index c24cd78497c2c6b2d4983baba1a8ba7fbc20b9ad..a00b2060c93c7cb7a3ca9cc168b0dab85645c007 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp @@ -37,7 +37,8 @@ int64_t UpdateStrategy::Execute( ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); return -1; } - auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version, true, + context->isEncryptDb, context->secretMetaKey); if (delegate == nullptr) { ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); return -1; diff --git a/datamgr_service/services/distributeddataservice/service/dumper/include/dump_helper.h b/datamgr_service/services/distributeddataservice/service/dumper/include/dump_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..6eadb2b4e2e1fc59a34a6da60586c151fb55f14b --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/dumper/include/dump_helper.h @@ -0,0 +1,94 @@ +/* +* 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 DISTRIBUTEDDATAMGR_SERVICE_DUMP_HELPER_H +#define DISTRIBUTEDDATAMGR_SERVICE_DUMP_HELPER_H + +#include +#include +#include +#include +#include + +#include "concurrent_map.h" +#include "dump/dump_manager.h" +#include "metadata/store_meta_data.h" +#include "types.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +class DumpHelper { + using Handler = std::function> &)>; + +public: + struct CommandNode { + std::string dumpName; + std::vector param; + int minParamsNum = 0; + int maxParamsNum = 0; + std::string parentNode; + std::string childNode; + std::vector handlers; + std::shared_ptr nextNode; + bool IsVoid() + { + auto config = DumpManager::GetInstance().GetConfig(this->dumpName); + return config.IsVoid(); + } + }; + struct ErrorInfo { + int32_t errorCode = 0; + std::string errorTime; + std::string errorInfo; + }; + API_EXPORT static DumpHelper &GetInstance(); + API_EXPORT void AddErrorInfo(int32_t errorCode, const std::string &errorInfo); + API_EXPORT bool Dump(int fd, const std::vector &args); + +private: + DumpHelper(); + ~DumpHelper() = default; + void GetCommandNodes(int fd, std::vector> &commands); + CommandNode GetCommand(const std::string &name); + void AddHeadNode(std::shared_ptr &command, std::shared_ptr &realHeadNode, bool &isAdded); + void AddNode(std::shared_ptr &command, std::shared_ptr &realHeadNode, bool &isAdded); + void ParseCommand(const std::vector &args, std::vector> &filterInfo); + int GetFormatMaxSize(); + + void RegisterErrorInfo(); + void DumpErrorInfo(int fd, std::map> ¶ms); + void RegisterHelpInfo(); + void DumpHelpInfo(int fd, std::map> ¶ms); + void RegisterAllInfo(); + void DumpAllInfo(int fd, std::map> ¶ms); + + std::string FormatHelpInfo(const std::string &cmdAbbr, const std::string &cmd, const std::string ¶Ext, + const std::string &info, int &formatMaxSize); + mutable std::mutex hidumperMutex_; + static constexpr int32_t MAX_FILTER_COUNT = 3; + static constexpr int32_t MAX_RECORED_ERROR = 10; + static constexpr int32_t DUMP_SYSTEM_START_YEAR = 1900; + static constexpr int32_t FORMAT_BLANK_SIZE = 32; + static constexpr int32_t FORMAT_FILL_SIZE = 6; + static constexpr char FORMAT_BLANK_SPACE = ' '; + static constexpr int32_t DUMP_COMMAND_PREFIX_SIZE = 1; + static constexpr const char *DUMP_COMMAND_PREFIX = "-"; + static constexpr const char *INDENTATION = " "; + static constexpr const char *SEPARATOR = "_"; + static constexpr int32_t PRINTF_COUNT_2 = 2; + + std::list errorInfo_; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_SERVICE_DUMP_HELPER_H diff --git a/datamgr_service/services/distributeddataservice/service/dumper/src/dump_helper.cpp b/datamgr_service/services/distributeddataservice/service/dumper/src/dump_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01a3e1408224c9de49bdcc6524572fa238fe7b44 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/dumper/src/dump_helper.cpp @@ -0,0 +1,336 @@ +/* +* 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. +*/ +#define LOG_TAG "DumpHelper" +#include "dump_helper.h" + +#include + +#include "log_print.h" +#include "rdb_types.h" +#include "runtime_config.h" +#include "string_ex.h" + +namespace OHOS::DistributedData { +DumpHelper::DumpHelper() +{ + Handler handlerErrorInfo = + std::bind(&DumpHelper::DumpErrorInfo, this, std::placeholders::_1, std::placeholders::_2); + Handler handlerHelpInfo = std::bind(&DumpHelper::DumpHelpInfo, this, std::placeholders::_1, std::placeholders::_2); + Handler handlerAllInfo = std::bind(&DumpHelper::DumpAllInfo, this, std::placeholders::_1, std::placeholders::_2); + RegisterErrorInfo(); + DumpManager::GetInstance().AddHandler("ERROR_INFO", uintptr_t(this), handlerErrorInfo); + RegisterHelpInfo(); + DumpManager::GetInstance().AddHandler("HELP_INFO", uintptr_t(this), handlerHelpInfo); + RegisterAllInfo(); + DumpManager::GetInstance().AddHandler("ALL_INFO", uintptr_t(this), handlerAllInfo); +} + +DumpHelper& DumpHelper::GetInstance() +{ + static DumpHelper instance; + return instance; +} + +bool DumpHelper::Dump(int fd, const std::vector &args) +{ + std::vector> commands; + ParseCommand(args, commands); + GetCommandNodes(fd, commands); + if (!(commands.empty())) { + std::shared_ptr tmpCommandNode; + for (auto& command : commands) { + std::map> params; + tmpCommandNode = command; + while (tmpCommandNode != nullptr) { + params.emplace(tmpCommandNode->dumpName, tmpCommandNode->param); + if (tmpCommandNode->nextNode == nullptr) { + for (auto& handler : tmpCommandNode->handlers) { + handler(fd, params); + } + } + tmpCommandNode = tmpCommandNode->nextNode; + } + } + } + return true; +} + +void DumpHelper::ParseCommand(const std::vector &args, std::vector> &commands) +{ + std::shared_ptr command; + std::vector tmpDumpNames; + if (args.size() == 0) { + command = std::make_shared(GetCommand("ALL_INFO")); + commands.emplace_back(command); + return; + } + for (size_t i = 0; i < args.size(); i++) { + std::vector param; + command = std::make_shared(GetCommand(args[i])); + if (!command->IsVoid()) { + auto it = find(tmpDumpNames.begin(), tmpDumpNames.end(), command->dumpName); + if (it != tmpDumpNames.end()) { + ZLOGE("The same command is not allowed"); + return; + } + commands.emplace_back(command); + tmpDumpNames.emplace_back(command->dumpName); + } else { + if (commands.empty()) { + ZLOGE("Invalid Format"); + return; + } + commands.back()->param.emplace_back(args[i]); + if (commands.back()->param.size() < commands.back()->minParamsNum || + commands.back()->param.size() > commands.back()->maxParamsNum) { + ZLOGE("The number of param criteria is not legal"); + return; + } + } + } + if (commands.size() == 0) { + ZLOGE("No command is entered or the command is invalid"); + return; + } +} + +DumpHelper::CommandNode DumpHelper::GetCommand(const std::string &name) +{ + auto config = DumpManager::GetInstance().GetConfig(name); + CommandNode command; + if (config.IsVoid()) { + return command; + } + command.dumpName = config.dumpName; + command.parentNode = config.parentNode; + command.childNode = config.childNode; + command.minParamsNum = config.minParamsNum; + command.maxParamsNum = config.maxParamsNum; + command.handlers = DumpManager::GetInstance().GetHandler(name); + command.nextNode = nullptr; + return command; +} + +void DumpHelper::GetCommandNodes(int fd, std::vector> &commands) +{ + for (auto i = 0; i < commands.size();) { + bool isAdded = false; + if (i == 0) { + i++; + continue; + } + if (commands[i]->parentNode.empty()) { + for (auto j = 0; j < i; j++) { + AddHeadNode(commands[i], commands[j], isAdded); + } + } else { + for (auto j = 0; j < i; j++) { + AddNode(commands[i], commands[j], isAdded); + } + } + if (!isAdded) { + i++; + } else { + commands.erase(commands.begin() + i); + } + } +} + +void DumpHelper::AddHeadNode(std::shared_ptr &command, std::shared_ptr &realHeadNode, + bool &isAdded) +{ + auto tmpCommandNode = command; + while (!(tmpCommandNode->childNode.empty())) { + if (tmpCommandNode->childNode == realHeadNode->dumpName) { + command->nextNode = realHeadNode; + realHeadNode = command; + isAdded = true; + } + tmpCommandNode = std::make_shared(GetCommand(tmpCommandNode->childNode)); + } +} + +void DumpHelper::AddNode(std::shared_ptr &command, std::shared_ptr &realHeadNode, + bool &isAdded) +{ + auto tmpCommandNode = command; + while (!(tmpCommandNode->parentNode.empty())) { + auto tmpRealHeadNode = realHeadNode; + while (tmpRealHeadNode != nullptr) { + if (tmpCommandNode->parentNode == tmpRealHeadNode->dumpName) { + command->nextNode = realHeadNode->nextNode; + realHeadNode->nextNode = command; + isAdded = true; + } + tmpRealHeadNode = tmpRealHeadNode->nextNode; + } + tmpCommandNode = std::make_shared(GetCommand(tmpCommandNode->parentNode)); + } +} + +void DumpHelper::RegisterErrorInfo() +{ + DumpManager::Config errorInfoConfig; + errorInfoConfig.fullCmd = "--error-info"; + errorInfoConfig.abbrCmd = "-e"; + errorInfoConfig.dumpName = "ERROR_INFO"; + errorInfoConfig.dumpCaption = { "| Display the recent error messages" }; + DumpManager::GetInstance().AddConfig(errorInfoConfig.dumpName, errorInfoConfig); +} + +void DumpHelper::DumpErrorInfo(int fd, std::map> ¶ms) +{ + std::string info; + for (const auto &it : errorInfo_) { + std::string errorCode = std::to_string(it.errorCode); + errorCode.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE); + info.append(it.errorTime).append(errorCode).append(it.errorInfo).append("\n"); + } + dprintf(fd, + "-------------------------------------RecentError------------------------------------\nDate " + " ErrorCode ErrorMessage\n%s\n", + info.c_str()); +} + +std::string DumpHelper::FormatHelpInfo(const std::string &cmd, const std::string &cmdAbbr, const std::string ¶Ext, + const std::string &info, int &formatMaxSize) +{ + std::string formatInfo; + formatInfo.append(" ").append(cmdAbbr).append(paraExt).append(", ").append(cmd).append(paraExt); + formatInfo.resize(formatMaxSize + FORMAT_FILL_SIZE, FORMAT_BLANK_SPACE); + formatInfo.append(info); + return formatInfo; +} + +int DumpHelper::GetFormatMaxSize() +{ + int formatMaxSize = 0; + auto dumpFactory = DumpManager::GetInstance().LoadConfig(); + dumpFactory.ForEach([&formatMaxSize](const auto &key, auto &value) { + if (key == "ALL_INFO") { + return false; + } + std::string helpInfo; + helpInfo.append(" ").append(value.fullCmd).append(", ").append(value.abbrCmd); + formatMaxSize = helpInfo.size() > formatMaxSize ? helpInfo.size() : formatMaxSize; + std::string helpInfoAdd; + if (value.countPrintf == PRINTF_COUNT_2) { + helpInfoAdd.append(" ") + .append(value.fullCmd) + .append(", ") + .append(value.abbrCmd) + .append(value.infoName) + .append(value.infoName); + formatMaxSize = helpInfoAdd.size() > formatMaxSize ? helpInfoAdd.size() : formatMaxSize; + } + return false; + }); + return formatMaxSize; +} + +void DumpHelper::RegisterHelpInfo() +{ + DumpManager::Config helpInfoConfig; + helpInfoConfig.fullCmd = "--help-info"; + helpInfoConfig.abbrCmd = "-h"; + helpInfoConfig.dumpName = "HELP_INFO"; + helpInfoConfig.dumpCaption = { "| Display this help message" }; + std::vector dumpCaption = { "| Display all the user statistics\n", "| Display the user statistics by " + "UserId\n" }; + DumpManager::GetInstance().AddConfig(helpInfoConfig.dumpName, helpInfoConfig); +} + +void DumpHelper::DumpHelpInfo(int fd, std::map> ¶ms) +{ + std::string info; + int formatMaxSize = GetFormatMaxSize(); + auto dumpFactory = DumpManager::GetInstance().LoadConfig(); + dumpFactory.ForEach([this, &info, &formatMaxSize](const auto &key, auto &value) { + if (key == "ALL_INFO") { + return false; + } + info.append(FormatHelpInfo(value.fullCmd, value.abbrCmd, "", value.dumpCaption[0], formatMaxSize)).append("\n"); + if (value.countPrintf == PRINTF_COUNT_2) { + info.append( + FormatHelpInfo(value.fullCmd, value.abbrCmd, value.infoName, value.dumpCaption[1], formatMaxSize)) + .append("\n"); + } + return false; + }); + dprintf(fd, + "Usage: hidumper -s 1301 -a \nwhere possible options include:\n%s\nWhen -u/-u , -b/-b " + " or -s/-s is simultaneously selected,\nwe display the lowest level statistics where -u " + "> -b > -s\nand the statistics is filterd by the upper level options\n", + info.c_str()); +} + +void DumpHelper::RegisterAllInfo() +{ + DumpManager::Config allInfoConfig; + allInfoConfig.fullCmd = "--all-info"; + allInfoConfig.abbrCmd = "-a"; + allInfoConfig.dumpName = "ALL_INFO"; + DumpManager::GetInstance().AddConfig(allInfoConfig.dumpName, allInfoConfig); +} + +void DumpHelper::DumpAllInfo(int fd, std::map> ¶ms) +{ + auto dumpFactory = DumpManager::GetInstance().LoadConfig(); + dumpFactory.ForEach([&fd, ¶ms](const auto &key, auto &value) { + if (key == "ALL_INFO" || key == "HELP_INFO") { + return false; + } + std::vector handlers = DumpManager::GetInstance().GetHandler(key); + if (!(handlers.empty())) { + for (auto handlerEach : handlers) { + handlerEach(fd, params); + } + } + return false; + }); +} + +void DumpHelper::AddErrorInfo(int32_t errorCode, const std::string &errorInfo) +{ + ErrorInfo error; + error.errorCode = errorCode; + error.errorInfo = errorInfo; + auto now = std::chrono::system_clock::now(); + uint64_t millSeconds = std::chrono::duration_cast(now.time_since_epoch()).count() - + (std::chrono::duration_cast(now.time_since_epoch()).count() * 1000); + time_t tt = std::chrono::system_clock::to_time_t(now); + auto ptm = localtime(&tt); + if (ptm != nullptr) { + char date[FORMAT_BLANK_SIZE] = { 0 }; + auto flag = sprintf_s(date, sizeof(date), "%04d-%02d-%02d %02d:%02d:%02d %03d", + (int)ptm->tm_year + DUMP_SYSTEM_START_YEAR, (int)ptm->tm_mon + 1, (int)ptm->tm_mday, (int)ptm->tm_hour, + (int)ptm->tm_min, (int)ptm->tm_sec, (int)millSeconds); + if (flag < 0) { + ZLOGE("get date failed"); + return; + } + std::string errorTime = date; + errorTime.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE); + error.errorTime = errorTime; + } + std::lock_guard lock(hidumperMutex_); + if (errorInfo_.size() + 1 > MAX_RECORED_ERROR) { + errorInfo_.pop_front(); + errorInfo_.push_back(error); + } else { + errorInfo_.push_back(error); + } +} +} // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 40a4709ab77e4bc00ee0ea14f8ed5adf098b1515..f89a6ce7cabc44db29456f0fca39163385884102 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -27,6 +27,7 @@ #include "crypto_manager.h" #include "device_manager_adapter.h" #include "directory/directory_manager.h" +#include "dump/dump_manager.h" #include "eventcenter/event_center.h" #include "ipc_skeleton.h" #include "log_print.h" @@ -45,6 +46,7 @@ using namespace OHOS::AppDistributedKv; using namespace OHOS::Security::AccessToken; using system_clock = std::chrono::system_clock; using DMAdapter = DistributedData::DeviceManagerAdapter; +using DumpManager = OHOS::DistributedData::DumpManager; __attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_; KVDBServiceImpl::Factory::Factory() { @@ -111,6 +113,32 @@ KVDBServiceImpl::KVDBServiceImpl() KVDBServiceImpl::~KVDBServiceImpl() { + DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); +} + +void KVDBServiceImpl::RegisterKvServiceInfo() +{ + OHOS::DistributedData::DumpManager::Config serviceInfoConfig; + serviceInfoConfig.fullCmd = "--feature-info"; + serviceInfoConfig.abbrCmd = "-f"; + serviceInfoConfig.dumpName = "FEATURE_INFO"; + serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; + DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); +} + +void KVDBServiceImpl::RegisterHandler() +{ + Handler handler = + std::bind(&KVDBServiceImpl::DumpKvServiceInfo, this, std::placeholders::_1, std::placeholders::_2); + DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); +} + +void KVDBServiceImpl::DumpKvServiceInfo(int fd, std::map> ¶ms) +{ + (void)params; + std::string info; + dprintf(fd, "-------------------------------------KVDBServiceInfo------------------------------\n%s\n", + info.c_str()); } Status KVDBServiceImpl::GetStoreIds(const AppId &appId, std::vector &storeIds) @@ -793,6 +821,7 @@ size_t KVDBServiceImpl::GetSyncDataSize(const std::string &deviceId) return totalSize; } + int32_t KVDBServiceImpl::OnBind(const BindInfo &bindInfo) { executors_ = bindInfo.executors; @@ -800,4 +829,11 @@ int32_t KVDBServiceImpl::OnBind(const BindInfo &bindInfo) KvStoreSyncManager::GetInstance()->SetThreadPool(bindInfo.executors); return 0; } + +int32_t KVDBServiceImpl::OnInitialize() +{ + RegisterKvServiceInfo(); + RegisterHandler(); + return SUCCESS; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index d41b5aade11d249c6e90bbbc88def7aeed87b515..083455f338cd428b82182b1ac3a88c55fd08ffc5 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -32,6 +32,7 @@ namespace OHOS::DistributedKv { class API_EXPORT KVDBServiceImpl final : public KVDBServiceStub { public: using DBLaunchParam = DistributedDB::AutoLaunchParam; + using Handler = std::function> &)>; using RefCount = DistributedData::RefCount; API_EXPORT KVDBServiceImpl(); virtual ~KVDBServiceImpl(); @@ -55,6 +56,7 @@ public: Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; int32_t OnBind(const BindInfo &bindInfo) override; + int32_t OnInitialize() override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; @@ -103,6 +105,9 @@ private: std::vector ConvertDevices(const std::vector &deviceIds) const; std::shared_ptr GetObservers(uint32_t tokenId, const std::string &storeId); void SaveLocalMetaData(const Options &options, const StoreMetaData &metaData); + void RegisterKvServiceInfo(); + void RegisterHandler(); + void DumpKvServiceInfo(int fd, std::map> ¶ms); static Factory factory_; ConcurrentMap syncAgents_; StoreCache storeCache_; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index 132faa2bb60c0386209fea0f7cb55dff0a20f559..b877d4b5198ed3f62f7baaec77c4327a7cc066cf 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -24,6 +24,7 @@ #include "checker/checker_manager.h" #include "device_manager_adapter.h" #include "directory/directory_manager.h" +#include "dump/dump_manager.h" #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" @@ -35,6 +36,7 @@ namespace OHOS::DistributedObject { using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using StoreMetaData = OHOS::DistributedData::StoreMetaData; using FeatureSystem = OHOS::DistributedData::FeatureSystem; +using DumpManager = OHOS::DistributedData::DumpManager; __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_; ObjectServiceImpl::Factory::Factory() { @@ -116,6 +118,8 @@ int32_t ObjectServiceImpl::OnInitialize() } ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", saveMeta.appId.c_str(), saveMeta.GetStoreAlias().c_str()); + RegisterObjectServiceInfo(); + RegisterHandler(); return OBJECT_SUCCESS; } @@ -281,6 +285,35 @@ ObjectServiceImpl::ObjectServiceImpl() { } +void ObjectServiceImpl::RegisterObjectServiceInfo() +{ + DumpManager::Config serviceInfoConfig; + serviceInfoConfig.fullCmd = "--feature-info"; + serviceInfoConfig.abbrCmd = "-f"; + serviceInfoConfig.dumpName = "FEATURE_INFO"; + serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; + DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); +} + +void ObjectServiceImpl::RegisterHandler() +{ + Handler handler = + std::bind(&ObjectServiceImpl::DumpObjectServiceInfo, this, std::placeholders::_1, std::placeholders::_2); + DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); +} + +void ObjectServiceImpl::DumpObjectServiceInfo(int fd, std::map> ¶ms) +{ + (void)params; + std::string info; + dprintf(fd, "-------------------------------------ObjectServiceInfo------------------------------\n%s\n", + info.c_str()); +} +ObjectServiceImpl::~ObjectServiceImpl() +{ + DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); +} + int32_t ObjectServiceImpl::OnBind(const BindInfo &bindInfo) { executors_ = bindInfo.executors; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h index caa1c34043f0123158a9d37f083972f69169afda..f06aab09bfd82a9caad74381dc9a1e25b617d510 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h @@ -25,8 +25,9 @@ namespace OHOS::DistributedObject { class API_EXPORT ObjectServiceImpl : public ObjectServiceStub { public: + using Handler = std::function> &)>; ObjectServiceImpl(); - + virtual ~ObjectServiceImpl(); int32_t ObjectStoreSave(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const std::map> &data, sptr callback) override; @@ -45,6 +46,7 @@ public: int32_t OnInitialize() override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnBind(const BindInfo &bindInfo) override; + void DumpObjectServiceInfo(int fd, std::map> ¶ms); private: using StaticActs = DistributedData::StaticActs; @@ -60,6 +62,8 @@ private: private: std::shared_ptr staticActs_; }; + void RegisterObjectServiceInfo(); + void RegisterHandler(); static Factory factory_; std::shared_ptr executors_; }; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp index f519b0854019e559dc80744895423fa56d139a44..61144f095ab752ea1686aa6bc4db4a42a1cc1b13 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -18,6 +18,8 @@ #include "cloud/schema_meta.h" #include "log_print.h" +#include "rdb_query.h" +#include "relational_store_manager.h" #include "value_proxy.h" #include "utils/anonymous.h" @@ -55,7 +57,15 @@ DBStatus RdbCloud::BatchDelete(const std::string &tableName, std::vector &data) { - auto cursor = cloudDB_->Query(tableName, ValueProxy::Convert(std::move(extend))); + auto [nodes, status] = ConvertQuery(extend); + std::shared_ptr cursor = nullptr; + if (status == GeneralError::E_OK && !nodes.empty()) { + RdbQuery query; + query.SetQueryNodes(tableName, std::move(nodes)); + cursor = cloudDB_->Query(query, ValueProxy::Convert(std::move(extend))); + } else { + cursor = cloudDB_->Query(tableName, ValueProxy::Convert(std::move(extend))); + } if (cursor == nullptr) { ZLOGE("cursor is null, table:%{public}s, extend:%{public}zu", Anonymous::Change(tableName).c_str(), extend.size()); @@ -128,4 +138,65 @@ DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) } return DBStatus::CLOUD_ERROR; } + +std::pair RdbCloud::ConvertQuery(RdbCloud::DBVBucket& extend) +{ + auto it = extend.find(TYPE_FIELD); + if (it == extend.end() || std::get(it->second) != static_cast(CloudQueryType::QUERY_FIELD)) { + return { {}, GeneralError::E_ERROR }; + } + it = extend.find(QUERY_FIELD); + if (it == extend.end()) { + ZLOGE("error, no QUERY_FIELD!"); + return { {}, GeneralError::E_ERROR }; + } + + auto bytes = std::get_if(&it->second); + std::vector nodes; + DBStatus status = DB_ERROR; + if (bytes != nullptr) { + nodes = DistributedDB::RelationalStoreManager::ParserQueryNodes(*bytes, status); + } + if (status != OK) { + ZLOGE("error, ParserQueryNodes failed, status:%{public}d", status); + return { {}, GeneralError::E_ERROR }; + } + return { ConvertQuery(std::move(nodes)), GeneralError::E_OK }; +} + +RdbCloud::QueryNodes RdbCloud::ConvertQuery(RdbCloud::DBQueryNodes&& nodes) +{ + QueryNodes queryNodes; + queryNodes.reserve(nodes.size()); + for (auto& node : nodes) { + QueryNode queryNode; + queryNode.fieldName = std::move(node.fieldName); + queryNode.fieldValue = ValueProxy::Convert(std::move(node.fieldValue)); + switch (node.type) { + case QueryNodeType::IN: + queryNode.op = QueryOperation::IN; + break; + case QueryNodeType::OR: + queryNode.op = QueryOperation::OR; + break; + case QueryNodeType::AND: + queryNode.op = QueryOperation::AND; + break; + case QueryNodeType::EQUAL_TO: + queryNode.op = QueryOperation::EQUAL_TO; + break; + case QueryNodeType::BEGIN_GROUP: + queryNode.op = QueryOperation::BEGIN_GROUP; + break; + case QueryNodeType::END_GROUP: + queryNode.op = QueryOperation::END_GROUP; + break; + default: + ZLOGE("invalid operation:0x%{public}d", node.type); + return {}; + } + queryNodes.emplace_back(std::move(queryNode)); + } + return queryNodes; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h index 161286ea5293657ad1cea77fad1dd9283f63dca6..dbe0563d5474f1dbc95a149a1946aa8395f1ff37 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -25,6 +25,7 @@ class RdbCloud : public DistributedDB::ICloudDb { public: using DBStatus = DistributedDB::DBStatus; using DBVBucket = DistributedDB::VBucket; + using DBQueryNodes = std::vector; explicit RdbCloud(std::shared_ptr cloudDB); virtual ~RdbCloud() = default; @@ -41,6 +42,11 @@ public: static DBStatus ConvertStatus(DistributedData::GeneralError error); private: + static constexpr const char *TYPE_FIELD = "#_type"; + static constexpr const char *QUERY_FIELD = "#_query"; + using QueryNodes = std::vector; + static std::pair ConvertQuery(DBVBucket& extend); + static QueryNodes ConvertQuery(DBQueryNodes&& nodes); static constexpr int32_t TO_MS = 1000; // s > ms std::shared_ptr cloudDB_; }; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index 5385952e3b5fa5aaa654f8b5ca520963669586b0..cc2b54c20ff7c7d6d177408913bef0dce2c2769f 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -198,13 +198,16 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &qu { DistributedDB::Query dbQuery; RdbQuery *rdbQuery = nullptr; + bool isPriority = false; auto ret = query.QueryInterface(rdbQuery); if (ret != GeneralError::E_OK || rdbQuery == nullptr) { dbQuery.FromTable(query.GetTables()); } else { dbQuery = rdbQuery->GetQuery(); + isPriority = rdbQuery->IsPriority(); } - auto dbMode = DistributedDB::SyncMode(mode); + auto syncMode = GeneralStore::GetSyncMode(mode); + auto dbMode = DistributedDB::SyncMode(syncMode); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " @@ -212,10 +215,11 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &qu devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), mode, wait); return GeneralError::E_ALREADY_CLOSED; } - auto status = (mode < NEARBY_END) + auto status = (syncMode < NEARBY_END) ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), wait != 0) - : (mode > NEARBY_END && mode < CLOUD_END) - ? delegate_->Sync(devices, dbMode, dbQuery, GetDBProcessCB(std::move(async)), wait) + : (syncMode > NEARBY_END && syncMode < CLOUD_END) + ? delegate_->Sync({ devices, dbMode, dbQuery, wait, isPriority }, GetDBProcessCB(std::move(async), + GetHighMode(mode))) : DistributedDB::INVALID_ARGS; return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; } @@ -297,13 +301,13 @@ RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) }; } -RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async) +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, int32_t highMode) { - if (!async) { - return [](auto &) {}; + if (!async && (highMode == MANUAL_SYNC_MODE || !async_)) { + return [](auto&) {}; } - return [async = std::move(async)](const std::map &processes) { + return [async, autoAsync = async_, highMode](const std::map& processes) { DistributedData::GenDetails details; for (auto &[id, process] : processes) { auto &detail = details[id]; @@ -321,7 +325,13 @@ RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async) table.download.untreated = table.download.total - table.download.success - table.download.failed; } } - async(details); + if (async) { + async(details); + } + + if (highMode == AUTO_SYNC_MODE && autoAsync) { + autoAsync(details); + } }; } @@ -409,6 +419,18 @@ bool RdbGeneralStore::IsValid() return delegate_ != nullptr; } +int32_t RdbGeneralStore::RegisterDetailProgressObserver(GeneralStore::DetailAsync async) +{ + async_ = std::move(async); + return GenErr::E_OK; +} + +int32_t RdbGeneralStore::UnregisterDetailProgressObserver() +{ + async_ = nullptr; + return GenErr::E_OK; +} + void RdbGeneralStore::ObserverProxy::OnChange(const DBChangedIF &data) { if (!HasWatcher()) { diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h index 915f7b5552f43a382596e3e4b13d77f5a166be15..5a8ea4b468f04ea5c5e7a1dc13998836d523934d 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -57,6 +57,8 @@ public: int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; + int32_t RegisterDetailProgressObserver(DetailAsync async) override; + int32_t UnregisterDetailProgressObserver() override; int32_t Close() override; int32_t AddRef() override; int32_t Release() override; @@ -88,13 +90,14 @@ private: std::string storeId_; }; DBBriefCB GetDBBriefCB(DetailAsync async); - DBProcessCB GetDBProcessCB(DetailAsync async); + DBProcessCB GetDBProcessCB(DetailAsync async, int32_t highMode = AUTO_SYNC_MODE); std::shared_ptr RemoteQuery(const std::string &device, const DistributedDB::RemoteCondition &remoteCondition); ObserverProxy observer_; RdbManager manager_; RdbDelegate *delegate_ = nullptr; + DetailAsync async_ = nullptr; std::shared_ptr rdbCloud_ {}; std::shared_ptr rdbLoader_ {}; BindInfo bindInfo_; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp index 1d9d74015d16237f7c5896830d665ba17fbd8b44..ede8209fb6c60f045839654e634ff9b21c9b92e3 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp @@ -16,6 +16,7 @@ #include "rdb_notifier_proxy.h" #include "itypes_util.h" #include "log_print.h" +#include "utils/anonymous.h" namespace OHOS::DistributedRdb { using NotifierIFCode = RelationalStore::IRdbNotifierInterfaceCode; @@ -44,7 +45,7 @@ int32_t RdbNotifierProxy::OnComplete(uint32_t seqNum, Details &&result) MessageOption option(MessageOption::TF_ASYNC); if (Remote()->SendRequest( static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_SYNC_COMPLETE), data, reply, option) != 0) { - ZLOGE("send request failed"); + ZLOGE("seqNum:%{public}u, send request failed", seqNum); return RDB_ERROR; } return RDB_OK; @@ -66,7 +67,28 @@ int32_t RdbNotifierProxy::OnChange(const Origin &origin, const PrimaryFields &pr MessageOption option; if (Remote()->SendRequest( static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_DATA_CHANGE), data, reply, option) != 0) { - ZLOGE("send request failed"); + ZLOGE("storeName:%{public}s, send request failed", DistributedData::Anonymous::Change(origin.store).c_str()); + return RDB_ERROR; + } + return RDB_OK; +} + +int32_t RdbNotifierProxy::OnComplete(const std::string& storeName, Details&& result) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!ITypesUtil::Marshal(data, storeName, result)) { + return RDB_ERROR; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (Remote()->SendRequest( + static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_AUTO_SYNC_COMPLETE), data, reply, option) != 0) { + ZLOGE("storeName:%{public}s, send request failed", DistributedData::Anonymous::Change(storeName).c_str()); return RDB_ERROR; } return RDB_OK; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h index 991fcae4f7e6106589828e1b00f12149b0f17d2b..d9b1d66a745539da6c4bfbae157627e28df82269 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.h @@ -31,6 +31,8 @@ public: int32_t OnComplete(uint32_t seqNum, Details &&result) override; + int32_t OnComplete(const std::string& storeName, Details &&result) override; + int32_t OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) override; private: diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp index 733427c97057620bd7b52c07dd55722765186e94..b805da46985e8b33a7e9381f1d2bfb3931de9dce 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp @@ -19,9 +19,6 @@ #include "value_proxy.h" namespace OHOS::DistributedRdb { using namespace DistributedData; - -RdbQuery::RdbQuery(bool isRemote) : isRemote_(isRemote) {} - bool RdbQuery::IsEqual(uint64_t tid) { return tid == TYPE_ID; @@ -32,13 +29,10 @@ std::vector RdbQuery::GetTables() return tables_; } -void RdbQuery::SetDevices(const std::vector &devices) -{ - devices_ = devices; -} - -void RdbQuery::SetSql(const std::string &sql, DistributedData::Values &&args) +void RdbQuery::MakeRemoteQuery(const std::string& devices, const std::string& sql, Values&& args) { + isRemote_ = true; + devices_ = { devices }; sql_ = sql; args_ = std::move(args); } @@ -55,13 +49,15 @@ std::vector RdbQuery::GetDevices() const void RdbQuery::FromTable(const std::vector &tables) { - ZLOGD("table count=%{public}zu", tables.size()); + ZLOGD("table size:%{public}zu", tables.size()); + tables_ = tables; query_.FromTable(tables); } void RdbQuery::MakeQuery(const PredicatesMemo &predicates) { - ZLOGD("table=%{public}zu", predicates.tables_.size()); + ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(), + predicates.devices_.size(), predicates.operations_.size()); query_ = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin()) : DistributedDB::Query::Select(); if (predicates.tables_.size() > 1) { @@ -76,6 +72,28 @@ void RdbQuery::MakeQuery(const PredicatesMemo &predicates) tables_ = predicates.tables_; } +void RdbQuery::MakeCloudQuery(const PredicatesMemo& predicates) +{ + ZLOGD("table size:%{public}zu, device size:%{public}zu, op size:%{public}zu", predicates.tables_.size(), + predicates.devices_.size(), predicates.operations_.size()); + devices_ = predicates.devices_; + tables_ = predicates.tables_; + if (predicates.operations_.empty() || predicates.tables_.size() != 1) { + query_ = DistributedDB::Query::Select(); + if (!predicates.tables_.empty()) { + query_.FromTable(predicates.tables_); + } + return; + } + query_ = DistributedDB::Query::Select().From(*predicates.tables_.begin()); + isPriority_ = true; + for (const auto& operation : predicates.operations_) { + if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) { + (this->*HANDLES[operation.operator_])(operation); + } + } +} + bool RdbQuery::IsRemoteQuery() { return isRemote_; @@ -88,6 +106,17 @@ DistributedDB::RemoteCondition RdbQuery::GetRemoteCondition() const return { sql_, bindArgs }; } +void RdbQuery::SetQueryNodes(const std::string& tableName, QueryNodes&& nodes) +{ + tables_ = { tableName }; + queryNodes_ = std::move(nodes); +} + +DistributedData::QueryNodes RdbQuery::GetQueryNodes(const std::string& tableName) +{ + return queryNodes_; +} + void RdbQuery::EqualTo(const RdbPredicateOperation &operation) { query_.EqualTo(operation.field_, operation.values_[0]); @@ -127,4 +156,24 @@ void RdbQuery::Limit(const RdbPredicateOperation &operation) } query_.Limit(limit, offset); } + +void RdbQuery::In(const RdbPredicateOperation& operation) +{ + query_.In(operation.field_, operation.values_); +} + +void RdbQuery::BeginGroup(const RdbPredicateOperation& operation) +{ + query_.BeginGroup(); +} + +void RdbQuery::EndGroup(const RdbPredicateOperation& operation) +{ + query_.EndGroup(); +} + +bool RdbQuery::IsPriority() +{ + return isPriority_; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h index 41088bd49ae29f7728c3656ace03ee48999d3621..380ee09759d34d2a2a595bad1d40f48fc7a838db 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h @@ -25,20 +25,22 @@ public: using Predicates = NativeRdb::RdbPredicates; static constexpr uint64_t TYPE_ID = 0x20000001; RdbQuery() = default; - explicit RdbQuery(bool isRemote); ~RdbQuery() override = default; bool IsEqual(uint64_t tid) override; std::vector GetTables() override; + void SetQueryNodes(const std::string& tableName, DistributedData::QueryNodes&& nodes) override; + DistributedData::QueryNodes GetQueryNodes(const std::string& tableName) override; std::vector GetDevices() const; DistributedDB::Query GetQuery() const; DistributedDB::RemoteCondition GetRemoteCondition() const; bool IsRemoteQuery(); - void SetDevices(const std::vector &devices); - void SetSql(const std::string &sql, DistributedData::Values &&args); + bool IsPriority(); void FromTable(const std::vector &tables); void MakeQuery(const PredicatesMemo &predicates); + void MakeRemoteQuery(const std::string &devices, const std::string &sql, DistributedData::Values &&args); + void MakeCloudQuery(const PredicatesMemo &predicates); private: void EqualTo(const RdbPredicateOperation& operation); @@ -47,6 +49,9 @@ private: void Or(const RdbPredicateOperation& operation); void OrderBy(const RdbPredicateOperation& operation); void Limit(const RdbPredicateOperation& operation); + void In(const RdbPredicateOperation& operation); + void BeginGroup(const RdbPredicateOperation& operation); + void EndGroup(const RdbPredicateOperation& operation); using PredicateHandle = void (RdbQuery::*)(const RdbPredicateOperation &operation); static constexpr inline PredicateHandle HANDLES[OPERATOR_MAX] = { &RdbQuery::EqualTo, @@ -55,15 +60,20 @@ private: &RdbQuery::Or, &RdbQuery::OrderBy, &RdbQuery::Limit, + &RdbQuery::BeginGroup, + &RdbQuery::EndGroup, + &RdbQuery::In, }; static constexpr inline uint32_t DECIMAL_BASE = 10; DistributedDB::Query query_; bool isRemote_ = false; + bool isPriority_ = false; std::string sql_; DistributedData::Values args_; std::vector devices_; std::vector tables_; + DistributedData::QueryNodes queryNodes_; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index 2bef5ae732dcc388951babd7e377cac93392eddf..52042a8c5178ee577ff95de1da6853660130fabd 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -22,6 +22,7 @@ #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" #include "directory/directory_manager.h" +#include "dump/dump_manager.h" #include "eventcenter/event_center.h" #include "ipc_skeleton.h" #include "log_print.h" @@ -48,6 +49,7 @@ using namespace OHOS::DistributedData; using namespace OHOS::Security::AccessToken; using DistributedDB::RelationalStoreManager; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using DumpManager = OHOS::DistributedData::DumpManager; using system_clock = std::chrono::system_clock; constexpr uint32_t ITERATE_TIMES = 10000; @@ -87,7 +89,7 @@ RdbServiceImpl::RdbServiceImpl() }); auto process = [this](const Event &event) { auto &evt = static_cast(event); - auto storeInfo = evt.GetStoreInfo(); + auto &storeInfo = evt.GetStoreInfo(); StoreMetaData meta; meta.storeId = storeInfo.storeName; meta.bundleName = storeInfo.bundleName; @@ -105,6 +107,7 @@ RdbServiceImpl::RdbServiceImpl() ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); return; } + store->RegisterDetailProgressObserver(GetCallbacks(meta.tokenId, storeInfo.storeName)); }; EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); } @@ -153,22 +156,23 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) { - OnClientDied(pid); - return E_OK; -} - -void RdbServiceImpl::OnClientDied(pid_t pid) -{ - ZLOGI("client dead pid=%{public}d", pid); - syncAgents_.EraseIf([pid](auto &key, SyncAgent &agent) { + ZLOGI("client dead, tokenId:%{public}d, pid:%{public}d ", tokenId, pid); + syncAgents_.EraseIf([pid](auto& key, SyncAgent& agent) { if (agent.pid_ != pid) { return false; } if (agent.watcher_ != nullptr) { agent.watcher_->SetNotifier(nullptr); } + auto stores = AutoCache::GetInstance().GetStoresIfPresent(key); + for (auto store : stores) { + if (store != nullptr) { + store->UnregisterDetailProgressObserver(); + } + } return true; }); + return E_OK; } bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::string& storeName) @@ -284,6 +288,25 @@ AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::str return { agent.watcher_ }; } +RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const std::string& storeName) +{ + sptr notifier = nullptr; + syncAgents_.ComputeIfPresent(tokenId, [&storeName, ¬ifier](auto, SyncAgent& syncAgent) { + if (syncAgent.callBackStores_.count(storeName) != 0) { + notifier = syncAgent.notifier_; + } + return true; + }); + if (notifier == nullptr) { + return nullptr; + } + return [notifier, storeName](const GenDetails& details) { + if (notifier != nullptr) { + notifier->OnComplete(storeName, HandleGenDetails(details)); + } + }; +} + int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet) { @@ -296,10 +319,8 @@ int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::stri ZLOGE("store is null"); return RDB_ERROR; } - auto values = ValueProxy::Convert(selectionArgs); - RdbQuery rdbQuery(true); - rdbQuery.SetDevices({ device }); - rdbQuery.SetSql(sql, std::move(values)); + RdbQuery rdbQuery; + rdbQuery.MakeRemoteQuery(device, sql, ValueProxy::Convert(selectionArgs)); auto cursor = store->Query("", rdbQuery); if (cursor == nullptr) { ZLOGE("Query failed, cursor is null"); @@ -337,10 +358,12 @@ int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option } RdbQuery rdbQuery; rdbQuery.MakeQuery(predicates); + auto devices = rdbQuery.GetDevices().empty() ? DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()) + : DmAdapter::ToUUID(rdbQuery.GetDevices()); if (!option.isAsync) { Details details = {}; auto status = store->Sync( - DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, rdbQuery, + devices, option.mode, rdbQuery, [&details, ¶m](const GenDetails &result) mutable { ZLOGD("Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); @@ -355,7 +378,7 @@ int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option ZLOGD("seqNum=%{public}u", option.seqNum); auto tokenId = IPCSkeleton::GetCallingTokenID(); return store->Sync( - DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, rdbQuery, + devices, option.mode, rdbQuery, [this, tokenId, seqNum = option.seqNum](const GenDetails &result) mutable { OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result)); }, @@ -373,7 +396,7 @@ void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService:: std::shared_ptr query = nullptr; if (!predicates.tables_.empty()) { query = std::make_shared(); - query->FromTable(predicates.tables_); + query->MakeCloudQuery(predicates); } GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum]( const GenDetails &result) mutable { @@ -386,9 +409,12 @@ void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService:: async(HandleGenDetails(details)); } }; - - auto info = ChangeEvent::EventInfo(option.mode, (option.isAsync ? 0 : WAIT_TIME), - (option.isAsync && option.seqNum == 0), query, (option.isAsync ? asyncCallback : syncCallback)); + auto mixMode = GeneralStore::MixMode(option.mode, + option.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE); + auto info = ChangeEvent::EventInfo(mixMode, (option.isAsync ? 0 : WAIT_TIME), option.isAutoSync, query, + option.isAutoSync ? nullptr + : option.isAsync ? asyncCallback + : syncCallback); auto evt = std::make_unique(std::move(storeInfo), std::move(info)); EventCenter::GetInstance().PostEvent(std::move(evt)); } @@ -415,7 +441,8 @@ int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOp return true; }); if (isCreate) { - AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_)); + AutoCache::GetInstance().SetObserver(tokenId, RemoveSuffix(param.storeName_), + GetWatchers(tokenId, param.storeName_)); } return RDB_OK; } @@ -440,13 +467,64 @@ int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam ¶m, const Subscribe return true; }); if (destroyed) { - AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_)); + AutoCache::GetInstance().SetObserver(tokenId, RemoveSuffix(param.storeName_), + GetWatchers(tokenId, param.storeName_)); } return RDB_OK; } -int32_t RdbServiceImpl::OnInitialize() +int32_t RdbServiceImpl::RegisterAutoSyncCallback(const RdbSyncerParam& param, + std::shared_ptr observer) { + pid_t pid = IPCSkeleton::GetCallingPid(); + auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto storeName = RemoveSuffix(param.storeName_); + bool isCreate = false; + syncAgents_.Compute(tokenId, [pid, ¶m, &storeName, &isCreate](auto, SyncAgent& agent) { + if (pid != agent.pid_) { + agent.ReInit(pid, param.bundleName_); + } + auto it = agent.callBackStores_.find(storeName); + if (it == agent.callBackStores_.end()) { + agent.callBackStores_.insert(std::make_pair(storeName, 0)); + isCreate = true; + } + agent.callBackStores_[storeName]++; + return true; + }); + if (isCreate) { + auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId, storeName); + if (!stores.empty() && *stores.begin() != nullptr) { + (*stores.begin())->RegisterDetailProgressObserver(GetCallbacks(tokenId, storeName)); + } + } + return RDB_OK; +} + +int32_t RdbServiceImpl::UnregisterAutoSyncCallback(const RdbSyncerParam& param, + std::shared_ptr observer) +{ + auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto storeName = RemoveSuffix(param.storeName_); + bool destroyed = false; + syncAgents_.ComputeIfPresent(tokenId, [&storeName, &destroyed](auto, SyncAgent& agent) { + auto it = agent.callBackStores_.find(storeName); + if (it == agent.callBackStores_.end()) { + return true; + } + it->second--; + if (it->second <= 0) { + agent.callBackStores_.erase(it); + destroyed = true; + } + return true; + }); + if (destroyed) { + auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId, storeName); + if (!stores.empty() && *stores.begin() != nullptr) { + (*stores.begin())->UnregisterDetailProgressObserver(); + } + } return RDB_OK; } @@ -511,6 +589,7 @@ StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m) metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData)); metaData.appType = "harmony"; metaData.hapName = param.hapName_; + metaData.customDir = param.customDir_; metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_; metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); metaData.isEncrypt = param.isEncrypt_; @@ -653,6 +732,7 @@ void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName) { pid_ = pid; count_ = 0; + callBackStores_.clear(); bundleName_ = bundleName; notifier_ = nullptr; if (watcher_ != nullptr) { @@ -721,4 +801,39 @@ int32_t RdbServiceImpl::RdbStatic::OnClearAppStorage(const std::string &bundleNa { return CloseStore(bundleName, user, index, tokenId); } + +void RdbServiceImpl::RegisterRdbServiceInfo() +{ + DumpManager::Config serviceInfoConfig; + serviceInfoConfig.fullCmd = "--feature-info"; + serviceInfoConfig.abbrCmd = "-f"; + serviceInfoConfig.dumpName = "FEATURE_INFO"; + serviceInfoConfig.dumpCaption = { "| Display all the service statistics" }; + DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig); +} + +void RdbServiceImpl::RegisterHandler() +{ + Handler handler = + std::bind(&RdbServiceImpl::DumpRdbServiceInfo, this, std::placeholders::_1, std::placeholders::_2); + DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler); +} +void RdbServiceImpl::DumpRdbServiceInfo(int fd, std::map> ¶ms) +{ + (void)params; + std::string info; + dprintf(fd, "-------------------------------------RdbServiceInfo------------------------------\n%s\n", + info.c_str()); +} +int32_t RdbServiceImpl::OnInitialize() +{ + RegisterRdbServiceInfo(); + RegisterHandler(); + return RDB_OK; +} + +RdbServiceImpl::~RdbServiceImpl() +{ + DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h index c8999344b5fe44257d3d267953c718e4b91b4a47..75d878b40a456ea0e94e70efb3187fb24c1f6b95 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -38,9 +38,10 @@ class API_EXPORT RdbServiceImpl : public RdbServiceStub { public: using StoreMetaData = OHOS::DistributedData::StoreMetaData; using SecretKeyMetaData = DistributedData::SecretKeyMetaData; + using DetailAsync = DistributedData::GeneralStore::DetailAsync; + using Handler = std::function> &)>; RdbServiceImpl(); - - void OnClientDied(pid_t pid); + virtual ~RdbServiceImpl(); /* IPC interface */ std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; @@ -61,6 +62,12 @@ public: int32_t UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) override; + int32_t RegisterAutoSyncCallback(const RdbSyncerParam& param, + std::shared_ptr observer) override; + + int32_t UnregisterAutoSyncCallback(const RdbSyncerParam& param, + std::shared_ptr observer) override; + int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) override; @@ -79,6 +86,7 @@ private: struct SyncAgent { pid_t pid_ = 0; int32_t count_ = 0; + std::map callBackStores_; std::string bundleName_; sptr notifier_ = nullptr; std::shared_ptr watcher_ = nullptr; @@ -110,6 +118,12 @@ private: static constexpr inline uint32_t WAIT_TIME = 30 * 1000; + void RegisterRdbServiceInfo(); + + void RegisterHandler(); + + void DumpRdbServiceInfo(int fd, std::map> ¶ms); + void DoCloudSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); @@ -118,6 +132,8 @@ private: Watchers GetWatchers(uint32_t tokenId, const std::string &storeName); + DetailAsync GetCallbacks(uint32_t tokenId, const std::string &storeName); + bool CheckAccess(const std::string& bundleName, const std::string& storeName); std::shared_ptr GetStore(const RdbSyncerParam& param); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 2e42628bb02e1350b45e69cdf4b5f75cfd90f2e5..9c461576b491cd09e2e366d1cf61140303e8a60b 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -227,4 +227,38 @@ int RdbServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageP } return RDB_ERROR; } + +int32_t RdbServiceStub::OnRemoteRegisterDetailProgressObserver(MessageParcel& data, MessageParcel& reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = RegisterAutoSyncCallback(param, nullptr); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteUnregisterDetailProgressObserver(MessageParcel& data, MessageParcel& reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = UnregisterAutoSyncCallback(param, nullptr); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h index 8b4aff5f3f16ed68fb212749b47063a6953c46fb..5ccd8e98c14e4eff7523b1c596fc7b9710cfe364 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -50,6 +50,10 @@ private: int32_t OnRemoteDoUnSubscribe(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteRegisterDetailProgressObserver(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteUnregisterDetailProgressObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); @@ -65,7 +69,11 @@ private: [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNSUBSCRIBE)] = &RdbServiceStub::OnRemoteDoUnSubscribe, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_REMOTE_QUERY)] = &RdbServiceStub::OnRemoteDoRemoteQuery, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_SCHEMA)] = &RdbServiceStub::OnGetSchema, - [static_cast(RdbServiceCode::RDB_SERVICE_CMD_DELETE)] = &RdbServiceStub::OnDelete + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_DELETE)] = &RdbServiceStub::OnDelete, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_REGISTER_AUTOSYNC_PROGRESS_OBSERVER)] = + &RdbServiceStub::OnRemoteRegisterDetailProgressObserver, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNREGISTER_AUTOSYNC_PROGRESS_OBSERVER)] = + &RdbServiceStub::OnRemoteUnregisterDetailProgressObserver }; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp index b2be4ffad6853f4b7c08564983f6567c73de4163..ea46d686f3ac677b94f9cb877607882f9e5f5262 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp @@ -58,6 +58,16 @@ ValueProxy::Values ValueProxy::Convert(std::vector &&val return proxy; } +ValueProxy::Values ValueProxy::Convert(std::vector &&values) +{ + Values proxy; + proxy.value_.reserve(values.size()); + for (auto &value : values) { + proxy.value_.emplace_back(Convert(std::move(value))); + } + return proxy; +} + ValueProxy::Bucket ValueProxy::Convert(DistributedData::VBucket &&bucket) { ValueProxy::Bucket proxy; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h index 272f78a98dc005ae399a4d1fc93ff8eb1b679d9f..829540eec07734e4c78060ae66b6cc879efa2635 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h @@ -197,6 +197,7 @@ public: static Value Convert(DistributedDB::Type &&value); static Values Convert(DistributedData::Values &&values); static Values Convert(std::vector &&values); + static Values Convert(std::vector &&values); static Bucket Convert(DistributedData::VBucket &&bucket); static Bucket Convert(NativeRdb::ValuesBucket &&bucket); static Bucket Convert(DistributedDB::VBucket &&bucket); diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn index ce20d4ff04053001c25fe116590e55ce64076f6c..1c1232651604863413012c2ceffc3851724d4835 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn @@ -58,9 +58,22 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/app/src/checker/bundle_checker.cpp", + "${data_service_path}/app/src/checker/system_checker.cpp", + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", "${data_service_path}/service/cloud/cloud_service_impl.cpp", "${data_service_path}/service/cloud/cloud_service_stub.cpp", "${data_service_path}/service/cloud/sync_manager.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.cpp", "${data_service_path}/service/rdb/rdb_asset_loader.cpp", "${data_service_path}/service/rdb/rdb_cloud.cpp", "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", @@ -81,7 +94,6 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", - "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn index e781b60393ec3e441569de4a77fdde89cf88eaf7..9be8455ccf04bf989411a26ef17c70ebcd88aba3 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -23,6 +23,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/adapter/include", "${data_service_path}/app/src", "${data_service_path}/framework/include", + "${data_service_path}/service/crypto/include", "${data_service_path}/service/data_share/common", "${data_service_path}/service/data_share/data", "${data_service_path}/service/data_share/strategies", @@ -45,6 +46,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/service/crypto/src/crypto_manager.cpp", "${data_service_path}/service/data_share/common/app_connect_manager.cpp", "${data_service_path}/service/data_share/common/base64_utils.cpp", "${data_service_path}/service/data_share/common/bundle_mgr_proxy.cpp", @@ -93,7 +95,6 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/framework:distributeddatasvcfwk", "${data_service_path}/service/data_share:data_share_service", - "${data_service_path}/service/data_share/gaussdb_rd:gaussdb_rd", ] external_deps = [ @@ -110,7 +111,9 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "data_share:datashare_common", "device_manager:devicemanagersdk", "hilog:libhilog", + "huks:libhukssdk", "ipc:ipc_core", + "kv_store:distributeddb", "relational_store:native_rdb", "relational_store:rdb_bms_adapter", "relational_store:rdb_data_share_adapter", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn index 16a96c164b1b00a3572fa4c588ce0ff9e6d2dea5..60532ecba51345685601b54cac4fe6c1da0c1ec9 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -59,6 +59,19 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/app/src/checker/bundle_checker.cpp", + "${data_service_path}/app/src/checker/system_checker.cpp", + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.cpp", "${data_service_path}/service/rdb/rdb_asset_loader.cpp", "${data_service_path}/service/rdb/rdb_cloud.cpp", "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", @@ -79,7 +92,6 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", - "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp index 3e6235bd2cd8e23d7660c4b70c5ddddc6b9ff107..14ec295a819d9804b800dae5cd5f00a57192493e 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp @@ -18,6 +18,7 @@ #include #include +#include "ipc_skeleton.h" #include "udmf_service_impl.h" #include "message_parcel.h" #include "securec.h" @@ -28,9 +29,16 @@ namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS.UDMF.UdmfService"; constexpr uint32_t CODE_MIN = 0; constexpr uint32_t CODE_MAX = 10; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; bool OnRemoteRequestFuzz(const uint8_t* data, size_t size) { + std::shared_ptr udmfServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + udmfServiceImpl->OnBind( + { "UdmfServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp index e701685cbf7b5ebd79295a170d5960466dabc31b..fb072eed9895ada81767bf2926eb579109f80026 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp @@ -117,6 +117,14 @@ int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin &origin, const G } return GeneralError::E_ERROR; } +int32_t GeneralStoreMock::RegisterDetailProgressObserver(GeneralStore::DetailAsync async) +{ + return 0; +} +int32_t GeneralStoreMock::UnregisterDetailProgressObserver() +{ + return 0; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h index 2ccbf8875599110ee561c27952ee11da1bf4ea6d..3fcaaa5c7c5e200c5d694cc05cc030873d4726df 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h @@ -47,6 +47,8 @@ public: int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; + int32_t RegisterDetailProgressObserver(DetailAsync async) override; + int32_t UnregisterDetailProgressObserver() override; int32_t Close() override; int32_t AddRef() override; int32_t Release() override; diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp index 8177d0f8387181009f45f37b5487cde50d7ed947..8dc6e121ee266f3ac63b94335f3ec2bd689abbc6 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_service_impl_test.cpp @@ -26,6 +26,7 @@ #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "mock/db_store_mock.h" +#include "mock/general_store_mock.h" #include "rdb_notifier_stub.h" #include "rdb_service_impl.h" #include "store/auto_cache.h" @@ -90,8 +91,9 @@ __attribute__((used)) TestChecker TestChecker::instance_; class NotifierMock : public RdbNotifierStub { public: NotifierMock(const SyncCompleteHandler& syncCompleteHandler = nullptr, + const AutoSyncCompleteHandler &autoSyncCompleteHandler = nullptr, const DataChangeHandler& dataChangeHandler = nullptr) - : RdbNotifierStub(syncCompleteHandler, dataChangeHandler) + : RdbNotifierStub(syncCompleteHandler, autoSyncCompleteHandler, dataChangeHandler) { } virtual ~NotifierMock() = default; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn index 4e33af71348067ff7bb2e149d7d99d311e3a8537..2cc49d43eaf1b6a128f5b074402c1cbad9c35672 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn @@ -25,9 +25,11 @@ config("module_public_config") { "${data_service_path}/service/udmf/preprocess", "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", + "${data_service_path}/service/bootstrap/include", "${device_manager_path}/interfaces/inner_kits/native_cpp/include", "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_path}/framework/libs/distributeddb/interfaces/include", "${kv_store_common_path}", "${udmf_path}/framework/common", "${udmf_path}/interfaces/innerkits/common", @@ -37,8 +39,6 @@ config("module_public_config") { ohos_shared_library("udmf_server") { sources = [ - "data_manager.cpp", - "lifecycle/clean_after_get.cpp", "lifecycle/clean_on_startup.cpp", "lifecycle/clean_on_timeout.cpp", "lifecycle/lifecycle_manager.cpp", @@ -58,6 +58,7 @@ ohos_shared_library("udmf_server") { deps = [ "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", ] external_deps = [ @@ -69,7 +70,7 @@ ohos_shared_library("udmf_server") { "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", - "kv_store:distributeddata_inner", + "kv_store:distributeddb", "udmf:udmf_client", ] diff --git a/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp deleted file mode 100644 index b8c38af536b0d229ecd2174ac0285eca9776eafb..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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. - */ -#define LOG_TAG "DataManager" - -#include "data_manager.h" - -#include "checker_manager.h" -#include "dfx_types.h" -#include "file.h" -#include "lifecycle/lifecycle_manager.h" -#include "log_print.h" -#include "preprocess_utils.h" -#include "uri_permission_manager.h" -#include "uri.h" - -namespace OHOS { -namespace UDMF { -const std::string MSDP_PROCESS_NAME = "msdp_sa"; -const std::string DATA_PREFIX = "udmf://"; -DataManager::DataManager() -{ - authorizationMap_[UD_INTENTION_MAP.at(UD_INTENTION_DRAG)] = MSDP_PROCESS_NAME; - CheckerManager::GetInstance().LoadCheckers(); -} - -DataManager::~DataManager() -{ -} - -DataManager &DataManager::GetInstance() -{ - static DataManager instance; - return instance; -} - -int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key) -{ - if (unifiedData.IsEmpty()) { - ZLOGE("Invalid parameters, have no record"); - return E_INVALID_PARAMETERS; - } - - if (!UnifiedDataUtils::IsValidIntention(option.intention)) { - ZLOGE("Invalid parameters intention: %{public}d.", option.intention); - return E_INVALID_PARAMETERS; - } - - // imput runtime info before put it into store and save one privilege - if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) { - ZLOGE("Imputation failed"); - return E_UNKNOWN; - } - - std::string intention = unifiedData.GetRuntime()->key.intention; - if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { - int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); - if (ret != E_OK) { - ZLOGE("SetRemoteUri failed, ret: %{public}d.", ret); - return ret; - } - } - - for (const auto &record : unifiedData.GetRecords()) { - record->SetUid(PreProcessUtils::IdGenerator()); - } - - auto store = storeCache_.GetStore(intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); - return E_DB_ERROR; - } - - if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) { - ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str()); - return E_DB_ERROR; - } - - if (store->Put(unifiedData) != E_OK) { - ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str()); - return E_DB_ERROR; - } - key = unifiedData.GetRuntime()->key.GetUnifiedKey(); - ZLOGD("Put unified data successful, key: %{public}s.", key.c_str()); - return E_OK; -} - -int32_t DataManager::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) -{ - UnifiedKey key(query.key); - if (!key.IsValid()) { - ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); - return E_INVALID_PARAMETERS; - } - auto store = storeCache_.GetStore(key.intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - int32_t res = store->Get(query.key, unifiedData); - if (res != E_OK) { - ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str()); - return res; - } - - std::shared_ptr runtime = unifiedData.GetRuntime(); - if (static_cast(unifiedData.GetRecords().size()) != runtime->recordTotalNum) { - ZLOGE("Get data from DB is incomplete, key: %{public}s, expected recordsNum is %{public}u, not %{public}zu.", - query.key.c_str(), runtime->recordTotalNum, unifiedData.GetRecords().size()); - return E_NOT_FOUND; - } - - CheckerManager::CheckInfo info; - info.tokenId = query.tokenId; - if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !CheckPermissionInCache(query)) { - return E_NO_PERMISSION; - } - - if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { - int32_t ret = ProcessingUri(query, unifiedData); - if (ret != E_OK) { - ZLOGE("DragUriProcessing failed. ret=%{public}d", ret); - return E_NO_PERMISSION; - } - } - - if (LifeCycleManager::GetInstance().DeleteOnGet(key) != E_OK) { - ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - privilegeCache_.erase(query.key); - - PreProcessUtils::SetRemoteData(unifiedData); - return E_OK; -} - -bool DataManager::CheckPermissionInCache(const QueryOption &query) -{ - auto iter = privilegeCache_.find(query.key); - if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) { - return true; - } - return false; -} - -int32_t DataManager::ProcessingUri(const QueryOption &query, UnifiedData &unifiedData) -{ - std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); - auto records = unifiedData.GetRecords(); - if (localDeviceId != unifiedData.GetRuntime()->deviceId) { - for (auto record : records) { - if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - std::string remoteUri = file->GetRemoteUri(); - if (remoteUri.empty()) { - ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str()); - continue; - } - file->SetUri(remoteUri); // cross dev, need dis path. - } - } - } - - std::string bundleName; - if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { - ZLOGE("GetHapBundleNameByToken fail, key=%{public}s.", query.key.c_str()); - return E_ERROR; - } - for (auto record : records) { - if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { - auto file = static_cast(record.get()); - if (file->GetUri().empty()) { - ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str()); - continue; - } - Uri uri(file->GetUri()); - if (uri.GetAuthority().empty()) { - ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str()); - continue; - } - if (UriPermissionManager::GetInstance().GrantUriPermission(file->GetUri(), bundleName) != E_OK) { - ZLOGE("GrantUriPermission fail, uriAuthority=%{public}s, bundleName=%{public}s, key=%{public}s.", - uri.GetAuthority().c_str(), bundleName.c_str(), query.key.c_str()); - return E_NO_PERMISSION; - } - } - } - return E_OK; -} - -int32_t DataManager::RetrieveBatchData(const QueryOption &query, std::vector &unifiedDataSet) -{ - std::vector dataSet; - std::shared_ptr store; - auto status = QueryDataCommon(query, dataSet, store); - if (status != E_OK) { - ZLOGE("QueryDataCommon failed."); - return status; - } - if (dataSet.empty()) { - ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); - return E_OK; - } - for (auto &data : dataSet) { - PreProcessUtils::SetRemoteData(data); - unifiedDataSet.push_back(data); - } - return E_OK; -} - -int32_t DataManager::UpdateData(const QueryOption &query, UnifiedData &unifiedData) -{ - UnifiedKey key(query.key); - if (!key.IsValid()) { - ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); - return E_INVALID_PARAMETERS; - } - if (unifiedData.IsEmpty()) { - ZLOGE("Invalid parameters, unified data has no record."); - return E_INVALID_PARAMETERS; - } - auto store = storeCache_.GetStore(key.intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - - UnifiedData data; - int32_t res = store->Get(query.key, data); - if (res != E_OK) { - ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); - return res; - } - if (data.IsEmpty()) { - ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str()); - return E_INVALID_PARAMETERS; - } - std::shared_ptr runtime = data.GetRuntime(); - runtime->lastModifiedTime = PreProcessUtils::GetTimeStamp(); - unifiedData.SetRuntime(*runtime); - for (auto &record : unifiedData.GetRecords()) { - record->SetUid(PreProcessUtils::IdGenerator()); - } - if (store->Update(unifiedData) != E_OK) { - ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - return E_OK; -} -int32_t DataManager::DeleteData(const QueryOption &query, std::vector &unifiedDataSet) -{ - std::vector dataSet; - std::shared_ptr store; - auto status = QueryDataCommon(query, dataSet, store); - if (status != E_OK) { - ZLOGE("QueryDataCommon failed."); - return status; - } - if (dataSet.empty()) { - ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); - return E_OK; - } - std::shared_ptr runtime; - std::vector deleteKeys; - for (const auto &data : dataSet) { - runtime = data.GetRuntime(); - unifiedDataSet.push_back(data); - deleteKeys.push_back(runtime->key.key); - } - if (store->DeleteBatch(deleteKeys) != E_OK) { - ZLOGE("Remove data failed."); - return E_DB_ERROR; - } - return E_OK; -} - -int32_t DataManager::GetSummary(const QueryOption &query, Summary &summary) -{ - UnifiedKey key(query.key); - if (!key.IsValid()) { - ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); - return E_INVALID_PARAMETERS; - } - - auto store = storeCache_.GetStore(key.intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - - if (store->GetSummary(query.key, summary) != E_OK) { - ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - return E_OK; -} - -int32_t DataManager::AddPrivilege(const QueryOption &query, const Privilege &privilege) -{ - UnifiedKey key(query.key); - if (!key.IsValid()) { - ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); - return E_INVALID_PARAMETERS; - } - - std::string processName; - if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) { - return E_UNKNOWN; - } - - if (processName != authorizationMap_[key.intention]) { - ZLOGE("Process: %{public}s have no permission", processName.c_str()); - return E_NO_PERMISSION; - } - - auto store = storeCache_.GetStore(key.intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - - UnifiedData data; - int32_t res = store->Get(query.key, data); - if (res == E_NOT_FOUND) { - privilegeCache_[query.key] = privilege; - ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); - return E_OK; - } - if (res != E_OK) { - ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str()); - return res; - } - data.GetRuntime()->privileges.emplace_back(privilege); - if (store->Update(data) != E_OK) { - ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - return E_OK; -} - -int32_t DataManager::Sync(const QueryOption &query, const std::vector &devices) -{ - UnifiedKey key(query.key); - if (!key.IsValid()) { - ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); - return E_INVALID_PARAMETERS; - } - - auto store = storeCache_.GetStore(key.intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - - if (store->Sync(devices) != E_OK) { - ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } - return E_OK; -} - -int32_t DataManager::QueryDataCommon( - const QueryOption &query, std::vector &dataSet, std::shared_ptr &store) -{ - auto find = UD_INTENTION_MAP.find(query.intention); - std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; - if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { - ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); - return E_INVALID_PARAMETERS; - } - std::string dataPrefix = DATA_PREFIX + intention; - UnifiedKey key(query.key); - key.IsValid(); - if (intention.empty()) { - dataPrefix = key.key; - intention = key.intention; - } - ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str()); - store = storeCache_.GetStore(intention); - if (store == nullptr) { - ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); - return E_DB_ERROR; - } - if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { - ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); - return E_DB_ERROR; - } - return E_OK; -} -} // namespace UDMF -} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp index eef045ff90bd94a6724d0e52ef8d83fd304c1519..993a7c25007fa5cda09ae6961a022fa6162ca258 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.cpp @@ -17,12 +17,12 @@ namespace OHOS { namespace UDMF { -Status CleanOnStartup::DeleteOnTimeout(const std::string &intention) +Status CleanOnStartup::OnTimeout(const std::string &intention) { return E_OK; } -Status CleanOnStartup::DeleteOnGet(const UnifiedKey &key) +Status CleanOnStartup::OnGot(const UnifiedKey &key) { return E_OK; } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h index b269743aa5617be3c2513563c6bc9f422afcc8fe..1a37c2c6dedc0210f49e66b918b79730bbf6e112 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_startup.h @@ -20,8 +20,8 @@ namespace OHOS { namespace UDMF { class CleanOnStartup : public LifeCyclePolicy { public: - Status DeleteOnTimeout(const std::string &intention) override; - Status DeleteOnGet(const UnifiedKey &key) override; + Status OnTimeout(const std::string &intention) override; + Status OnGot(const UnifiedKey &key) override; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp index 6b36eadfd8ea07e11db5b94827b8b7399885b88d..804ff884f2d8e2498e10bd7ea9cac29afc5d1bee 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.cpp @@ -17,12 +17,12 @@ namespace OHOS { namespace UDMF { -Status CleanOnTimeout::DeleteOnStart(const std::string &intention) +Status CleanOnTimeout::OnStart(const std::string &intention) { - return LifeCyclePolicy::DeleteOnTimeout(intention); + return LifeCyclePolicy::OnTimeout(intention); } -Status CleanOnTimeout::DeleteOnGet(const UnifiedKey &key) +Status CleanOnTimeout::OnGot(const UnifiedKey &key) { return E_OK; } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h index d86be2584fe12bfbd66957e8d1aa1dad1e11876c..30bf8bc3fb6b8091c2f8ad0e642bae8241ba2363 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_on_timeout.h @@ -20,8 +20,8 @@ namespace OHOS { namespace UDMF { class CleanOnTimeout : public LifeCyclePolicy { public: - Status DeleteOnStart(const std::string &intention) override; - Status DeleteOnGet(const UnifiedKey &key) override; + Status OnStart(const std::string &intention) override; + Status OnGot(const UnifiedKey &key) override; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp index fb8710e6d22c7b71915fadcd6bdce799fb4326f7..cf62738750ed99a51759cde90934f7f61a1965cb 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp @@ -23,7 +23,7 @@ namespace OHOS { namespace UDMF { -std::shared_ptr LifeCycleManager::executorPool_ = std::make_shared(2, 1); +using CleanAfterGet = LifeCyclePolicy; std::unordered_map> LifeCycleManager::intentionPolicy_ = { { UD_INTENTION_MAP.at(UD_INTENTION_DRAG), std::make_shared() }, }; @@ -34,7 +34,7 @@ LifeCycleManager &LifeCycleManager::GetInstance() return instance; } -Status LifeCycleManager::DeleteOnGet(const UnifiedKey &key) +Status LifeCycleManager::OnGot(const UnifiedKey &key) { auto findPolicy = intentionPolicy_.find(key.intention); if (findPolicy == intentionPolicy_.end()) { @@ -42,10 +42,10 @@ Status LifeCycleManager::DeleteOnGet(const UnifiedKey &key) return E_INVALID_PARAMETERS; } auto policy = findPolicy->second; - return policy->DeleteOnGet(key); + return policy->OnGot(key); } -Status LifeCycleManager::DeleteOnStart() +Status LifeCycleManager::OnStart() { Status status = E_OK; std::string errorInfo; @@ -53,10 +53,10 @@ Status LifeCycleManager::DeleteOnStart() if (lifeCyclePolicy == nullptr) { continue; } - Status delStatus = lifeCyclePolicy->DeleteOnStart(intention); + Status delStatus = lifeCyclePolicy->OnStart(intention); if (delStatus != E_OK) { status = delStatus; - errorInfo += intention + " "; + errorInfo += intention + " "; } } if (status != E_OK) { @@ -65,10 +65,13 @@ Status LifeCycleManager::DeleteOnStart() return status; } -Status LifeCycleManager::DeleteOnSchedule() +Status LifeCycleManager::StartLifeCycleTimer() { - ExecutorPool::TaskId taskId = - executorPool_->Schedule(&LifeCycleManager::DeleteOnTimeout, LifeCyclePolicy::INTERVAL); + if (executors_ == nullptr) { + ZLOGE("Executors_ is nullptr."); + return E_ERROR; + } + ExecutorPool::TaskId taskId = executors_->Schedule(GetTask(), LifeCyclePolicy::INTERVAL); if (taskId == ExecutorPool::INVALID_TASK_ID) { ZLOGE("ExecutorPool Schedule failed."); return E_ERROR; @@ -77,25 +80,31 @@ Status LifeCycleManager::DeleteOnSchedule() return E_OK; } -Status LifeCycleManager::DeleteOnTimeout() +ExecutorPool::Task LifeCycleManager::GetTask() { - Status status = E_OK; - std::string errorInfo; - std::shared_ptr lifeCyclePolicy; - for (auto &[intention, lifeCyclePolicy] : intentionPolicy_) { - if (lifeCyclePolicy == nullptr) { - continue; + return [this] { + Status status = E_OK; + std::string errorInfo; + for (auto &[intention, lifeCyclePolicy] : intentionPolicy_) { + if (lifeCyclePolicy == nullptr) { + continue; + } + Status delStatus = lifeCyclePolicy->OnTimeout(intention); + if (delStatus != E_OK) { + status = delStatus; + errorInfo += intention + " "; + } } - Status delStatus = lifeCyclePolicy->DeleteOnTimeout(intention); - if (delStatus != E_OK) { - status = delStatus; - errorInfo += intention + " "; + if (status != E_OK) { + ZLOGW("fail, status = %{public}d, intention = [%{public}s].", status, errorInfo.c_str()); } - } - if (status != E_OK) { - ZLOGW("fail, status = %{public}d, intention = [%{public}s].", status, errorInfo.c_str()); - } - return status; + return status; + }; +} + +void LifeCycleManager::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; } } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h index dd90d0df7fa69fe0b13930eb3aafd152aea4d652..b1420ae25a3b94d772c708727608fdfb3428cf4d 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.h @@ -21,25 +21,25 @@ #include #include -#include "clean_after_get.h" #include "clean_on_startup.h" #include "clean_on_timeout.h" #include "executor_pool.h" -#include "lifecycle_policy.h" namespace OHOS { namespace UDMF { class LifeCycleManager { public: static LifeCycleManager &GetInstance(); - Status DeleteOnGet(const UnifiedKey &key); - Status DeleteOnStart(); - Status DeleteOnSchedule(); + Status OnGot(const UnifiedKey &key); + Status OnStart(); + Status StartLifeCycleTimer(); + void SetThreadPool(std::shared_ptr executors); private: - static std::shared_ptr executorPool_; + ExecutorPool::Task GetTask(); static std::unordered_map> intentionPolicy_; - static Status DeleteOnTimeout(); + static constexpr const char *DATA_PREFIX = "udmf://"; + std::shared_ptr executors_; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp index 7e790fb94a4ee964e99ae4efb1a0280ca3225aa5..359dc9f409065f743099b5b83e64587752f050a1 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.cpp @@ -16,20 +16,16 @@ #include "lifecycle_policy.h" -#include - #include "log_print.h" #include "preprocess/preprocess_utils.h" namespace OHOS { namespace UDMF { using namespace std::chrono; -const LifeCyclePolicy::Duration LifeCyclePolicy::INTERVAL = milliseconds(60 * 60 * 1000); -const std::string LifeCyclePolicy::DATA_PREFIX = "udmf://"; -Status LifeCyclePolicy::DeleteOnGet(const UnifiedKey &key) +Status LifeCyclePolicy::OnGot(const UnifiedKey &key) { - auto store = storeCache_.GetStore(key.intention); + auto store = StoreCache::GetInstance().GetStore(key.intention); if (store == nullptr) { ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); return E_DB_ERROR; @@ -41,9 +37,9 @@ Status LifeCyclePolicy::DeleteOnGet(const UnifiedKey &key) return E_OK; } -Status LifeCyclePolicy::DeleteOnStart(const std::string &intention) +Status LifeCyclePolicy::OnStart(const std::string &intention) { - auto store = storeCache_.GetStore(intention); + auto store = StoreCache::GetInstance().GetStore(intention); if (store == nullptr) { ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; @@ -55,9 +51,9 @@ Status LifeCyclePolicy::DeleteOnStart(const std::string &intention) return E_OK; } -Status LifeCyclePolicy::DeleteOnTimeout(const std::string &intention) +Status LifeCyclePolicy::OnTimeout(const std::string &intention) { - auto store = storeCache_.GetStore(intention); + auto store = StoreCache::GetInstance().GetStore(intention); if (store == nullptr) { ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); return E_DB_ERROR; @@ -88,7 +84,7 @@ Status LifeCyclePolicy::GetTimeoutKeys( ZLOGD("entries is empty."); return E_OK; } - auto curTime = PreProcessUtils::GetTimeStamp(); + auto curTime = PreProcessUtils::GetTimestamp(); for (const auto &data : datas) { if (curTime > data.GetRuntime()->createTime + duration_cast(interval).count() || curTime < data.GetRuntime()->createTime) { diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h index b1ba7e040675c5daa999ce004ab8010064eea6a2..ed3fd63f3a020228a317049da10fbdfdec568b30 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h @@ -15,6 +15,7 @@ #ifndef UDMF_LIFECYCLE_POLICY_H #define UDMF_LIFECYCLE_POLICY_H +#include #include #include @@ -26,18 +27,16 @@ namespace UDMF { class LifeCyclePolicy { public: using Duration = std::chrono::steady_clock::duration; - static const Duration INTERVAL; + static constexpr Duration INTERVAL = std::chrono::milliseconds(60 * 60 * 1000); virtual ~LifeCyclePolicy() = default; - virtual Status DeleteOnGet(const UnifiedKey &key); - virtual Status DeleteOnStart(const std::string &intention); - virtual Status DeleteOnTimeout(const std::string &intention); - -private: + virtual Status OnGot(const UnifiedKey &key); + virtual Status OnStart(const std::string &intention); + virtual Status OnTimeout(const std::string &intention); virtual Status GetTimeoutKeys( const std::shared_ptr &store, Duration interval, std::vector &timeoutKeys); - static const std::string DATA_PREFIX; - StoreCache storeCache_; +private: + static constexpr const char *DATA_PREFIX = "udmf://"; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp index 10c8ddece8107fec4ad4efcba2f7feb7e9f378e3..273e2186cb3bedf3705b40c45f4a96cd5eb1de64 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -16,6 +16,7 @@ #include "preprocess_utils.h" +#include #include #include "accesstoken_kit.h" @@ -27,9 +28,12 @@ #include "log_print.h" #include "remote_file_share.h" #include "uri.h" +#include "utils/crypto.h" namespace OHOS { namespace UDMF { static constexpr int ID_LEN = 32; +static constexpr int MINIMUM = 48; +static constexpr int MAXIMUM = 121; const char SPECIAL = '^'; const std::string PERMISSION_PROXY_AUTHORIZATION_URI = "ohos.permission.PROXY_AUTHORIZATION_URI"; using namespace Security::AccessToken; @@ -39,18 +43,18 @@ int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption & { auto it = UD_INTENTION_MAP.find(option.intention); if (it == UD_INTENTION_MAP.end()) { - return E_UNKNOWN; + return E_ERROR; } std::string bundleName; GetHapBundleNameByToken(option.tokenId, bundleName); std::string intention = it->second; - UnifiedKey key(intention, bundleName, IdGenerator()); + UnifiedKey key(intention, bundleName, GenerateId()); Privilege privilege; privilege.tokenId = option.tokenId; Runtime runtime; runtime.key = key; runtime.privileges.emplace_back(privilege); - runtime.createTime = GetTimeStamp(); + runtime.createTime = GetTimestamp(); runtime.sourcePackage = bundleName; runtime.createPackage = bundleName; runtime.deviceId = GetLocalDeviceId(); @@ -59,22 +63,19 @@ int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption & return E_OK; } -std::string PreProcessUtils::IdGenerator() +std::string PreProcessUtils::GenerateId() { - std::random_device randomDevice; - int minimum = 48; - int maximum = 121; - std::uniform_int_distribution distribution(minimum, maximum); + std::vector randomDevices = DistributedData::Crypto::Random(ID_LEN, MINIMUM, MAXIMUM); std::stringstream idStr; - for (int32_t i = 0; i < ID_LEN; i++) { - auto asc = distribution(randomDevice); + for (auto &randomDevice : randomDevices) { + auto asc = randomDevice; asc = asc >= SPECIAL ? asc + 1 : asc; idStr << static_cast(asc); } return idStr.str(); } -time_t PreProcessUtils::GetTimeStamp() +time_t PreProcessUtils::GetTimestamp() { std::chrono::time_point tp = std::chrono::time_point_cast(std::chrono::system_clock::now()); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h index d9fa54f3857546633a67d93e1661f61aab2967f6..6f3ecce63f8dab593a74fc85c4853dbe3ce3afd6 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -28,8 +28,8 @@ namespace UDMF { class PreProcessUtils { public: static int32_t RuntimeDataImputation(UnifiedData &data, CustomOption &option); - static std::string IdGenerator(); - static time_t GetTimeStamp(); + static std::string GenerateId(); + static time_t GetTimestamp(); static int32_t GetHapUidByToken(uint32_t tokenId); static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 612d4ec51b1e451a7d46264e1cb379897bdfbeda..3fdd332de798863cca4e2428fc23415600cec036 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -18,28 +18,33 @@ #include #include +#include #include "log_print.h" -#include "same_process_ipc_guard.h" +#include "ipc_skeleton.h" #include "tlv_util.h" +#include "account/account_delegate.h" +#include "metadata/store_meta_data.h" +#include "metadata/meta_data_manager.h" +#include "metadata/appid_meta_data.h" +#include "device_manager_adapter.h" +#include "bootstrap.h" +#include "directory/directory_manager.h" namespace OHOS { namespace UDMF { -using namespace DistributedKv; -const AppId RuntimeStore::APP_ID = { "distributeddata" }; -const std::string RuntimeStore::DATA_PREFIX = "udmf://"; -const std::string RuntimeStore::BASE_DIR = "/data/service/el1/public/database/distributeddata"; +using namespace DistributedDB; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; -RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_({ storeId }) +RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_(storeId) { UpdateTime(); - ZLOGI("Construct runtimeStore: %{public}s.", storeId_.storeId.c_str()); + ZLOGD("Construct runtimeStore: %{public}s.", storeId_.c_str()); } RuntimeStore::~RuntimeStore() { - ZLOGI("Destruct runtimeStore: %{public}s.", storeId_.storeId.c_str()); - Close(); + ZLOGD("Destruct runtimeStore: %{public}s.", storeId_.c_str()); } Status RuntimeStore::Put(const UnifiedData &unifiedData) @@ -54,7 +59,8 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str()); return E_WRITE_PARCEL_ERROR; } - Entry entry = { Key(unifiedKey), Value(runtimeBytes) }; + std::vector udKeyBytes = {unifiedKey.begin(), unifiedKey.end()}; + Entry entry = {udKeyBytes, runtimeBytes}; entries.push_back(entry); // add unified record @@ -65,8 +71,9 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) ZLOGI("Marshall unified record failed."); return E_WRITE_PARCEL_ERROR; } - - Entry entry = { Key(unifiedKey + "/" + record->GetUid()), Value(recordBytes) }; + std::string recordKey = unifiedKey + "/" + record->GetUid(); + std::vector keyBytes = {recordKey.begin(), recordKey.end() }; + Entry entry = { keyBytes, recordBytes }; entries.push_back(entry); } auto status = PutEntries(entries); @@ -85,7 +92,7 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); return E_NOT_FOUND; } - return UnMarshalEntries(key, entries, unifiedData); + return UnmarshalEntries(key, entries, unifiedData); } Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) @@ -164,9 +171,16 @@ Status RuntimeStore::DeleteBatch(const std::vector &unifiedKeys) Status RuntimeStore::Sync(const std::vector &devices) { UpdateTime(); - SameProcessIpcGuard ipcGuard; - DistributedKv::Status status = kvStore_->Sync(devices, SyncMode::PULL); - if (status != DistributedKv::Status::SUCCESS) { + if (devices.empty()) { + ZLOGE("devices empty, no need sync."); + return E_INVALID_PARAMETERS; + } + std::vector syncDevices = DmAdapter::ToUUID(devices); + auto onComplete = [this](const std::map &) { + ZLOGI("sync complete, %{public}s.", storeId_.c_str()); + }; + DBStatus status = kvStore_->Sync(syncDevices, SyncMode::SYNC_MODE_PULL_ONLY, onComplete); + if (status != DBStatus::OK) { ZLOGE("Sync kvStore failed, status: %{public}d.", status); return E_DB_ERROR; } @@ -194,7 +208,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector keySet; for (const auto &entry : entries) { - std::string keyStr = entry.key.ToString(); + std::string keyStr = {entry.key.begin(), entry.key.end()}; if (std::count(keyStr.begin(), keyStr.end(), '/') == SLASH_COUNT_IN_KEY) { keySet.emplace_back(keyStr); } @@ -202,7 +216,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vectorCloseKvStore(kvStore_.get()); } bool RuntimeStore::Init() { - Options options; - options.autoSync = false; - options.createIfMissing = true; - options.rebuild = true; - options.backup = false; - options.securityLevel = SecurityLevel::S1; - options.baseDir = BASE_DIR; - options.area = Area::EL1; - options.kvStoreType = KvStoreType::SINGLE_VERSION; - SameProcessIpcGuard ipcGuard; - DistributedKv::Status status = dataManager_.GetSingleKvStore(options, APP_ID, storeId_, kvStore_); - if (status != DistributedKv::Status::SUCCESS) { - ZLOGE("GetKvStore: %{public}s failed, status: %{public}d.", storeId_.storeId.c_str(), status); + SaveMetaData(); + DistributedDB::KvStoreNbDelegate::Option option; + option.createIfNecessary = true; + option.isMemoryDb = false; + option.createDirByStoreIdOnly = true; + option.isEncryptedDb = false; + option.isNeedRmCorruptedDb = true; + option.syncDualTupleMode = true; + option.secOption = {DistributedKv::SecurityLevel::S1, DistributedDB::ECE}; + DistributedDB::KvStoreNbDelegate *delegate = nullptr; + DBStatus status = DBStatus::NOT_SUPPORT; + delegateManager_->GetKvStore(storeId_, option, + [&delegate, &status](DBStatus dbStatus, KvStoreNbDelegate *nbDelegate) { + delegate = nbDelegate; + status = dbStatus; + }); + if (status != DBStatus::OK) { + ZLOGE("GetKvStore fail, status: %{public}d.", static_cast(status)); return false; } + + auto release = [this](KvStoreNbDelegate *delegate) { + ZLOGI("Release runtime kvStore."); + if (delegate == nullptr) { + return; + } + auto retStatus = delegateManager_->CloseKvStore(delegate); + if (retStatus != DBStatus::OK) { + ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); + } + }; + kvStore_ = std::shared_ptr(delegate, release); return true; } +void RuntimeStore::SaveMetaData() +{ + auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (localDeviceId.empty()) { + ZLOGE("failed to get local device id"); + return; + } + + uint32_t token = IPCSkeleton::GetSelfTokenID(); + const std::string userId = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token)); + DistributedData::StoreMetaData saveMeta; + saveMeta.appType = "harmony"; + saveMeta.deviceId = localDeviceId; + saveMeta.storeId = storeId_; + saveMeta.isAutoSync = false; + saveMeta.isBackup = false; + saveMeta.isEncrypt = false; + saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.user = userId; + saveMeta.account = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); + saveMeta.tokenId = token; + saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; + saveMeta.area = DistributedKv::Area::EL1; + saveMeta.uid = static_cast(getuid()); + saveMeta.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); + + SetDelegateManager(saveMeta.dataDir, saveMeta.appId, userId); + auto saved = DistributedData::MetaDataManager::GetInstance().SaveMeta(saveMeta.GetKey(), saveMeta); + if (!saved) { + ZLOGE("SaveMeta failed"); + return; + } + DistributedData::AppIDMetaData appIdMeta; + appIdMeta.bundleName = saveMeta.bundleName; + appIdMeta.appId = saveMeta.appId; + saved = DistributedData::MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true); + if (!saved) { + ZLOGE("Save appIdMeta failed"); + return; + } +} + +void RuntimeStore::SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId) +{ + delegateManager_ = std::make_shared(appId, userId); + DistributedDB::KvStoreConfig kvStoreConfig { dataDir }; + delegateManager_->SetKvStoreConfig(kvStoreConfig); +} + Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vector &entries) { - DataQuery query; - query.KeyPrefix(dataPrefix); - query.OrderByWriteTime(true); - auto status = kvStore_->GetEntries(query, entries); - if (status != DistributedKv::Status::SUCCESS) { + Query dbQuery = Query::Select(); + std::vector prefix = {dataPrefix.begin(), dataPrefix.end()}; + dbQuery.PrefixKey(prefix); + dbQuery.OrderByWriteTime(true); + DBStatus status = kvStore_->GetEntries(dbQuery, entries); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { ZLOGE("KvStore getEntries failed, status: %{public}d.", static_cast(status)); return E_DB_ERROR; } @@ -251,12 +334,12 @@ Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vector &entries) { size_t size = entries.size(); - DistributedKv::Status status; + DBStatus status; for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector batchEntries( + std::vector dbEntries( entries.begin() + index, entries.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->PutBatch(batchEntries); - if (status != DistributedKv::Status::SUCCESS) { + status = kvStore_->PutBatch(dbEntries); + if (status != DBStatus::OK) { ZLOGE("KvStore putBatch failed, status: %{public}d.", status); return E_DB_ERROR; } @@ -267,11 +350,11 @@ Status RuntimeStore::PutEntries(const std::vector &entries) Status RuntimeStore::DeleteEntries(const std::vector &keys) { size_t size = keys.size(); - DistributedKv::Status status; + DBStatus status; for (size_t index = 0; index < size; index += MAX_BATCH_SIZE) { - std::vector batchKeys(keys.begin() + index, keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); - status = kvStore_->DeleteBatch(batchKeys); - if (status != DistributedKv::Status::SUCCESS) { + std::vector dbKeys(keys.begin() + index, keys.begin() + std::min(index + MAX_BATCH_SIZE, size)); + status = kvStore_->DeleteBatch(dbKeys); + if (status != DBStatus::OK) { ZLOGE("KvStore deleteBatch failed, status: %{public}d.", status); return E_DB_ERROR; } @@ -279,13 +362,13 @@ Status RuntimeStore::DeleteEntries(const std::vector &keys) return E_OK; } -Status RuntimeStore::UnMarshalEntries(const std::string &key, std::vector &entries, UnifiedData &unifiedData) +Status RuntimeStore::UnmarshalEntries(const std::string &key, std::vector &entries, UnifiedData &unifiedData) { for (const auto &entry : entries) { - std::string keyStr = entry.key.ToString(); + std::string keyStr = {entry.key.begin(), entry.key.end()}; if (keyStr == key) { Runtime runtime; - auto runtimeTlv = TLVObject(const_cast &>(entry.value.Data())); + auto runtimeTlv = TLVObject(const_cast &>(entry.value)); if (!TLVUtil::Reading(runtime, runtimeTlv)) { ZLOGE("Unmarshall runtime info failed."); return E_READ_PARCEL_ERROR; @@ -293,7 +376,7 @@ Status RuntimeStore::UnMarshalEntries(const std::string &key, std::vector unifiedData.SetRuntime(runtime); } else if (keyStr.find(key) == 0) { std::shared_ptr record; - auto recordTlv = TLVObject(const_cast &>(entry.value.Data())); + auto recordTlv = TLVObject(const_cast &>(entry.value)); if (!TLVUtil::Reading(record, recordTlv)) { ZLOGE("Unmarshall unified record failed."); return E_READ_PARCEL_ERROR; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h index d01f17729a0a25e267176445bccc886b20c6928f..7fa8ff62d65ede33d9122a6bde525dd0adee133f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -16,10 +16,8 @@ #ifndef UDMF_RUNTIMESTORE_H #define UDMF_RUNTIMESTORE_H -#include "distributed_kv_data_manager.h" -#include "single_kvstore.h" - #include "store.h" +#include "kv_store_delegate_manager.h" namespace OHOS { namespace UDMF { @@ -40,19 +38,19 @@ public: bool Init() override; private: - static const DistributedKv::AppId APP_ID; - static const std::string DATA_PREFIX; - static const std::string BASE_DIR; + static constexpr const char *DATA_PREFIX = "udmf://"; static constexpr std::int32_t SLASH_COUNT_IN_KEY = 4; static constexpr std::int32_t MAX_BATCH_SIZE = 128; - DistributedKv::DistributedKvDataManager dataManager_; - std::shared_ptr kvStore_; - DistributedKv::StoreId storeId_; - Status GetEntries(const std::string &dataPrefix, std::vector &entries); - Status PutEntries(const std::vector &entries); - Status DeleteEntries(const std::vector &keys); - Status UnMarshalEntries( - const std::string &key, std::vector &entries, UnifiedData &unifiedData); + std::shared_ptr delegateManager_ = nullptr; + std::shared_ptr kvStore_; + std::string storeId_; + void SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId); + void SaveMetaData(); + Status GetEntries(const std::string &dataPrefix, std::vector &entries); + Status PutEntries(const std::vector &entries); + Status DeleteEntries(const std::vector &keys); + Status UnmarshalEntries( + const std::string &key, std::vector &entries, UnifiedData &unifiedData); }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h index a3fd85eba02780115812534612eefb671d713334..61f65dfb3ba50eb5dae006784b378cea15475721 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h @@ -16,9 +16,9 @@ #ifndef UDMF_STORE_H #define UDMF_STORE_H -#include -#include #include +#include +#include #include "error_code.h" #include "unified_data.h" diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp index 4944e2d9f432a142b4b73b9474f19620ab3c2af2..0b5c217708aae39881a705d16245fbfb3ca21b7f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -23,7 +23,11 @@ namespace OHOS { namespace UDMF { -std::shared_ptr StoreCache::executorPool_ = std::make_shared(2, 1); +StoreCache &StoreCache::GetInstance() +{ + static StoreCache instance; + return instance; +} std::shared_ptr StoreCache::GetStore(std::string intention) { @@ -48,7 +52,7 @@ std::shared_ptr StoreCache::GetStore(std::string intention) }); std::unique_lock lock(taskMutex_); - if (taskId_ == ExecutorPool::INVALID_TASK_ID) { + if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); } return store; @@ -60,17 +64,23 @@ void StoreCache::GarbageCollect() stores_.EraseIf([¤t](auto &key, std::shared_ptr &storePtr) { if (*storePtr < current) { ZLOGD("GarbageCollect, stores:%{public}s time limit, will be close.", key.c_str()); + storePtr->Close(); return true; } return false; }); std::unique_lock lock(taskMutex_); - if (!stores_.Empty()) { + if (!stores_.Empty() && executorPool_ != nullptr) { ZLOGD("GarbageCollect, stores size:%{public}zu", stores_.Size()); taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); } else { taskId_ = ExecutorPool::INVALID_TASK_ID; } } + +void StoreCache::SetThreadPool(std::shared_ptr executors) +{ + executorPool_ = executors; +} } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.h b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.h index a66e4c658ca62febeeb8c7dbf5d27a2ec5334c82..aa9ad330eff6e80874a43d735a351725c4cb7285 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.h @@ -29,8 +29,17 @@ namespace UDMF { class StoreCache { public: std::shared_ptr GetStore(std::string intention); + static StoreCache &GetInstance(); + void SetThreadPool(std::shared_ptr executors); private: + StoreCache() {} + + ~StoreCache() {} + + StoreCache(const StoreCache &obj) = delete; + StoreCache &operator=(const StoreCache &obj) = delete; + void GarbageCollect(); ConcurrentMap> stores_; @@ -38,7 +47,7 @@ private: ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; static constexpr int64_t INTERVAL = 1; // 1 min - static std::shared_ptr executorPool_; + std::shared_ptr executorPool_; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index b343283bdc90f86b07923efe2f7dd0f535a3cadf..8a1b5c1953fab61c92784e0380eadcf04450b517 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -18,17 +18,24 @@ #include "iservice_registry.h" -#include "data_manager.h" +#include "checker_manager.h" +#include "dfx_types.h" +#include "distributed_kv_data_manager.h" +#include "file.h" #include "lifecycle/lifecycle_manager.h" #include "log_print.h" #include "preprocess_utils.h" #include "reporter.h" +#include "uri_permission_manager.h" +#include "uri.h" namespace OHOS { namespace UDMF { using FeatureSystem = DistributedData::FeatureSystem; using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; using Reporter = OHOS::DistributedDataDfx::Reporter; +constexpr const char *MSDP_PROCESS_NAME = "msdp_sa"; +constexpr const char *DATA_PREFIX = "udmf://"; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -46,6 +53,12 @@ UdmfServiceImpl::Factory::~Factory() product_ = nullptr; } +UdmfServiceImpl::UdmfServiceImpl() +{ + authorizationMap_[UD_INTENTION_MAP.at(UD_INTENTION_DRAG)] = MSDP_PROCESS_NAME; + CheckerManager::GetInstance().LoadCheckers(); +} + int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { ZLOGD("start"); @@ -60,7 +73,7 @@ int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, res = E_ERROR; } else { msg.appId = bundleName; - res = DataManager::GetInstance().SaveData(option, unifiedData, key); + res = SaveData(option, unifiedData, key); } auto errFind = ERROR_MAP.find(res); msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; @@ -70,6 +83,57 @@ int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, return res; } +int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key) +{ + if (!unifiedData.IsValid()) { + ZLOGE("UnifiedData is invalid."); + return E_INVALID_PARAMETERS; + } + + if (!UnifiedDataUtils::IsValidIntention(option.intention)) { + ZLOGE("Invalid parameters intention: %{public}d.", option.intention); + return E_INVALID_PARAMETERS; + } + + // imput runtime info before put it into store and save one privilege + if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) { + ZLOGE("Imputation failed"); + return E_ERROR; + } + + std::string intention = unifiedData.GetRuntime()->key.intention; + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); + if (ret != E_OK) { + ZLOGE("SetRemoteUri failed, ret: %{public}d.", ret); + return ret; + } + } + + for (const auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::GenerateId()); + } + + auto store = StoreCache::GetInstance().GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) { + ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + if (store->Put(unifiedData) != E_OK) { + ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + key = unifiedData.GetRuntime()->key.GetUnifiedKey(); + ZLOGD("Put unified data successful, key: %{public}s.", key.c_str()); + return E_OK; +} + int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData) { ZLOGD("start"); @@ -84,7 +148,7 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD res = E_ERROR; } else { msg.appId = bundleName; - res = DataManager::GetInstance().RetrieveData(query, unifiedData); + res = RetrieveData(query, unifiedData); } auto errFind = ERROR_MAP.find(res); msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; @@ -94,54 +158,356 @@ int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedD return res; } +int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData) +{ + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + auto store = StoreCache::GetInstance().GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + int32_t res = store->Get(query.key, unifiedData); + if (res != E_OK) { + ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str()); + return res; + } + + if (!unifiedData.IsComplete()) { + ZLOGE("Get data from DB is incomplete, key: %{public}s.", query.key.c_str()); + return E_NOT_FOUND; + } + + CheckerManager::CheckInfo info; + info.tokenId = query.tokenId; + std::shared_ptr runtime = unifiedData.GetRuntime(); + if (runtime == nullptr) { + return E_DB_ERROR; + } + if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) { + return E_NO_PERMISSION; + } + + if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = ProcessUri(query, unifiedData); + if (ret != E_OK) { + ZLOGE("DragUriProcessing failed. ret=%{public}d", ret); + return E_NO_PERMISSION; + } + } + + if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + privilegeCache_.erase(query.key); + + PreProcessUtils::SetRemoteData(unifiedData); + return E_OK; +} + +bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query) +{ + auto iter = privilegeCache_.find(query.key); + if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) { + return true; + } + return false; +} + +int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData) +{ + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + auto records = unifiedData.GetRecords(); + if (unifiedData.GetRuntime() == nullptr) { + return E_DB_ERROR; + } + if (localDeviceId != unifiedData.GetRuntime()->deviceId) { + SetRemoteUri(query, records); + } + + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { + ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId); + return E_ERROR; + } + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + if (file->GetUri().empty()) { + ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str()); + continue; + } + Uri uri(file->GetUri()); + if (uri.GetAuthority().empty()) { + ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str()); + continue; + } + if (UriPermissionManager::GetInstance().GrantUriPermission(file->GetUri(), bundleName) != E_OK) { + ZLOGE("GrantUriPermission fail, uriAuthority=%{public}s, bundleName=%{public}s, key=%{public}s.", + uri.GetAuthority().c_str(), bundleName.c_str(), query.key.c_str()); + return E_NO_PERMISSION; + } + } + } + return E_OK; +} + +void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector> &records) +{ + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + std::string remoteUri = file->GetRemoteUri(); + if (remoteUri.empty()) { + ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str()); + continue; + } + file->SetUri(remoteUri); // cross dev, need dis path. + } + } +} + int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) { ZLOGD("start"); - return DataManager::GetInstance().RetrieveBatchData(query, unifiedDataSet); + std::vector dataSet; + std::shared_ptr store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + ZLOGE("QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); + return E_OK; + } + for (auto &data : dataSet) { + PreProcessUtils::SetRemoteData(data); + unifiedDataSet.push_back(data); + } + return E_OK; } int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData) { ZLOGD("start"); - return DataManager::GetInstance().UpdateData(query, unifiedData); + if (!unifiedData.IsValid()) { + ZLOGE("UnifiedData is invalid."); + return E_INVALID_PARAMETERS; + } + + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + auto store = StoreCache::GetInstance().GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData data; + int32_t res = store->Get(query.key, data); + if (res != E_OK) { + ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); + return res; + } + if (data.IsEmpty()) { + ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::shared_ptr runtime = data.GetRuntime(); + if (runtime == nullptr) { + return E_DB_ERROR; + } + runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); + unifiedData.SetRuntime(*runtime); + for (auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::GenerateId()); + } + if (store->Update(unifiedData) != E_OK) { + ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; } int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector &unifiedDataSet) { ZLOGD("start"); - return DataManager::GetInstance().DeleteData(query, unifiedDataSet); + std::vector dataSet; + std::shared_ptr store; + auto status = QueryDataCommon(query, dataSet, store); + if (status != E_OK) { + ZLOGE("QueryDataCommon failed."); + return status; + } + if (dataSet.empty()) { + ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); + return E_OK; + } + std::shared_ptr runtime; + std::vector deleteKeys; + for (const auto &data : dataSet) { + runtime = data.GetRuntime(); + if (runtime == nullptr) { + return E_DB_ERROR; + } + unifiedDataSet.push_back(data); + deleteKeys.push_back(runtime->key.key); + } + if (store->DeleteBatch(deleteKeys) != E_OK) { + ZLOGE("Remove data failed."); + return E_DB_ERROR; + } + return E_OK; } int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) { ZLOGD("start"); - return DataManager::GetInstance().GetSummary(query, summary); + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + auto store = StoreCache::GetInstance().GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + if (store->GetSummary(query.key, summary) != E_OK) { + ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; } int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege) { ZLOGD("start"); - return DataManager::GetInstance().AddPrivilege(query, privilege); + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + std::string processName; + if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) { + return E_ERROR; + } + + if (processName != authorizationMap_[key.intention]) { + ZLOGE("Process: %{public}s have no permission", processName.c_str()); + return E_NO_PERMISSION; + } + + auto store = StoreCache::GetInstance().GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData data; + int32_t res = store->Get(query.key, data); + if (res == E_NOT_FOUND) { + privilegeCache_[query.key] = privilege; + ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); + return E_OK; + } + if (res != E_OK) { + ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str()); + return res; + } + if (data.GetRuntime() == nullptr) { + return E_DB_ERROR; + } + data.GetRuntime()->privileges.emplace_back(privilege); + if (store->Update(data) != E_OK) { + ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; } int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) { ZLOGD("start"); - return DataManager::GetInstance().Sync(query, devices); + UnifiedKey key(query.key); + if (!key.IsValid()) { + ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); + return E_INVALID_PARAMETERS; + } + + auto store = StoreCache::GetInstance().GetStore(key.intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + + if (store->Sync(devices) != E_OK) { + ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + return E_OK; } int32_t UdmfServiceImpl::OnInitialize() { ZLOGD("start"); - Status status = LifeCycleManager::GetInstance().DeleteOnStart(); + Status status = LifeCycleManager::GetInstance().OnStart(); if (status != E_OK) { - ZLOGE("DeleteOnStart execute failed, status: %{public}d", status); + ZLOGE("OnStart execute failed, status: %{public}d", status); } - status = LifeCycleManager::GetInstance().DeleteOnSchedule(); + status = LifeCycleManager::GetInstance().StartLifeCycleTimer(); if (status != E_OK) { - ZLOGE("ScheduleTask start failed, status: %{public}d", status); + ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status); } return DistributedData::FeatureSystem::STUB_SUCCESS; } + +int32_t UdmfServiceImpl::QueryDataCommon( + const QueryOption &query, std::vector &dataSet, std::shared_ptr &store) +{ + auto find = UD_INTENTION_MAP.find(query.intention); + std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second; + if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) { + ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str()); + return E_INVALID_PARAMETERS; + } + std::string dataPrefix = DATA_PREFIX + intention; + UnifiedKey key(query.key); + key.IsValid(); + if (intention.empty()) { + dataPrefix = key.key; + intention = key.intention; + } + ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str()); + store = StoreCache::GetInstance().GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { + ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo) +{ + executors_ = bindInfo.executors; + StoreCache::GetInstance().SetThreadPool(bindInfo.executors); + LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors); + return 0; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h index 30b9dafd5be0142600e4fd5c71af2cee22acc334..fe4be6cbfdc742319bc7bab4e219499a05b02934 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -16,9 +16,16 @@ #ifndef UDMF_SERVICE_IMPL_H #define UDMF_SERVICE_IMPL_H +#include +#include +#include #include +#include "error_code.h" +#include "store_cache.h" #include "udmf_service_stub.h" +#include "unified_data.h" +#include "unified_types.h" namespace OHOS { namespace UDMF { @@ -27,7 +34,7 @@ namespace UDMF { */ class UdmfServiceImpl final : public UdmfServiceStub { public: - UdmfServiceImpl() = default; + UdmfServiceImpl(); ~UdmfServiceImpl() = default; int32_t SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) override; @@ -39,8 +46,15 @@ public: int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; int32_t Sync(const QueryOption &query, const std::vector &devices) override; int32_t OnInitialize() override; + int32_t OnBind(const BindInfo &bindInfo) override; private: + int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); + int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); + int32_t QueryDataCommon(const QueryOption &query, std::vector &dataSet, std::shared_ptr &store); + int32_t ProcessUri(const QueryOption &query, UnifiedData &unifiedData); + void SetRemoteUri(const QueryOption &query, std::vector> &records); + bool IsPermissionInCache(const QueryOption &query); class Factory { public: Factory(); @@ -50,6 +64,9 @@ private: std::shared_ptr product_; }; static Factory factory_; + std::map authorizationMap_; + std::map privilegeCache_; + std::shared_ptr executors_; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index d07e7e09b0f042f1f22ff6ec1ed95aadcce7c79d..018fe837292fba6c5e7c40b51fbbab934dafe585 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -17,6 +17,7 @@ #include "udmf_service_stub.h" #include +#include #include "accesstoken_kit.h" #include "ipc_skeleton.h" @@ -31,11 +32,13 @@ constexpr UdmfServiceStub::Handler UdmfServiceStub::HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)]; int UdmfServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) { - ZLOGI("start##code = %{public}u", code); + ZLOGI("start##code = %{public}u callingPid:%{public}u callingUid:%{public}u.", code, IPCSkeleton::GetCallingPid(), + IPCSkeleton::GetCallingUid()); std::u16string myDescripter = UdmfServiceStub::GetDescriptor(); std::u16string remoteDescripter = data.ReadInterfaceToken(); if (myDescripter != remoteDescripter) { - ZLOGE("end##descriptor checked fail"); + ZLOGE("end##descriptor checked fail,myDescripter = %{public}s,remoteDescripter = %{public}s.", + Str16ToStr8(myDescripter).c_str(), Str16ToStr8(remoteDescripter).c_str()); return -1; } if (static_cast(UdmfServiceInterfaceCode::CODE_HEAD) > code || @@ -54,20 +57,6 @@ int32_t UdmfServiceStub::OnSetData(MessageParcel &data, MessageParcel &reply) ZLOGE("Unmarshal customOption or unifiedData failed!"); return E_READ_PARCEL_ERROR; } - if (unifiedData.IsEmpty()) { - ZLOGE("Empty data without any record!"); - return E_INVALID_PARAMETERS; - } - if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { - ZLOGE("Exceeded data limit!"); - return E_INVALID_PARAMETERS; - } - for (const auto &record : unifiedData.GetRecords()) { - if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { - ZLOGE("Exceeded record limit!"); - return E_INVALID_PARAMETERS; - } - } uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); customOption.tokenId = token; std::string key; @@ -126,20 +115,6 @@ int32_t UdmfServiceStub::OnUpdateData(MessageParcel &data, MessageParcel &reply) ZLOGE("Unmarshal queryOption or unifiedData failed!"); return E_READ_PARCEL_ERROR; } - if (unifiedData.IsEmpty()) { - ZLOGE("Empty data without any record!"); - return E_INVALID_PARAMETERS; - } - if (unifiedData.GetSize() > UdmfService::MAX_DATA_SIZE) { - ZLOGE("Exceeded data limit!"); - return E_INVALID_PARAMETERS; - } - for (const auto &record : unifiedData.GetRecords()) { - if (record->GetSize() > UdmfService::MAX_RECORD_SIZE) { - ZLOGE("Exceeded record limit!"); - return E_INVALID_PARAMETERS; - } - } uint32_t token = static_cast(IPCSkeleton::GetCallingTokenID()); query.tokenId = token; int32_t status = UpdateData(query, unifiedData); @@ -225,19 +200,5 @@ int32_t UdmfServiceStub::OnSync(MessageParcel &data, MessageParcel &reply) } return E_OK; } - -/* - * Check whether the caller has the permission to access data. - */ -bool UdmfServiceStub::VerifyPermission(const std::string &permission) -{ -#ifdef UDMF_PERMISSION_ENABLED - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); - return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED; -#else - return true; -#endif // UDMF_PERMISSION_ENABLED -} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h index d3a739999eff4280cb5d19a98be564dab15c4aa2..908d64cafae4c094d4a114ba1bc1b2d3038b61f7 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -45,12 +45,6 @@ private: int32_t OnAddPrivilege(MessageParcel &data, MessageParcel &reply); int32_t OnSync(MessageParcel &data, MessageParcel &reply); - bool VerifyPermission(const std::string &permission); - - const std::string READ_PERMISSION = "ohos.permission.READ_UDMF_DATA"; - const std::string WRITE_PERMISSION = "ohos.permission.WRITE_UDMF_DATA"; - const std::string SYNC_PERMISSION = "ohos.permission.SYNC_UDMF_DATA"; - using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { &UdmfServiceStub::OnSetData, diff --git a/datamgr_service/services/distributeddataservice/test/BUILD.gn b/datamgr_service/services/distributeddataservice/test/BUILD.gn deleted file mode 100644 index b36942961b761f7f9708e8cbbca2ee86b6b2b83e..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/test/BUILD.gn +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2021 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. -import("//build/test.gni") - -############################################################################### - -group("fuzztest") { - testonly = true - deps = [] - deps += [ "fuzztest/schemaquery_fuzzer:fuzztest" ] -} - -############################################################################### - diff --git a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn deleted file mode 100644 index 2cc4e27734b93c9ab1a459852dcdae3d541667ff..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (c) 2022 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. - -#####################hydra-fuzz################### -import("//build/config/features.gni") -import("//build/test.gni") - -##############################fuzztest########################################## -ohos_fuzztest("SchemaQueryFuzzTest") { - module_out_path = "datamgr_service/distributeddb" - - include_dirs = [ - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//commonlibrary/c_utils/base/include", - "//third_party/jsoncpp/include/json", - "//third_party/skia/third_party/externals/spirv-headers/tools/buildHeaders/jsoncpp/dist/json", - "//third_party/skia/third_party/externals/swiftshader/third_party/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json", - "//third_party/jsoncpp/include/json", - "//third_party/grpc/src/core/lib/json", - "//third_party/sqlite/include", - "//third_party/googletest/googletest/include/gtest", - ] - - sources = [ "schemaquery_fuzzer.cpp" ] - - cflags = [ - "-g", - "-O0", - "-Wno-unused-variable", - "-fno-omit-frame-pointer", - ] - - fuzz_config_file = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer" - - deps = [ - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", - "//third_party/jsoncpp:jsoncpp", - "//third_party/openssl:libcrypto_shared", - ] - - defines = [ - "SQLITE_ENABLE_SNAPSHOT", - "_LARGEFILE64_SOURCE", - "_FILE_OFFSET_BITS=64", - "SQLITE_HAS_CODEC", - "SQLITE_ENABLE_JSON1", - "USING_HILOG_LOGGER", - "USE_SQLITE_SYMBOLS", - "USING_DB_JSON_EXTRACT_AUTOMATICALLY", - "LOW_LEVEL_MEM_DEV", - "JSONCPP_USE_BUILDER", - "OMIT_FLATBUFFER", - "RELATIONAL_STORE", - "SQLITE_DISTRIBUTE_RELATIONAL", - "OPENSSL_SUPPRESS_DEPRECATED", - ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - "ipc:ipc_core", - ] -} - -############################################################################### -group("fuzztest") { - testonly = true - deps = [] - deps += [ - # deps file - ":SchemaQueryFuzzTest", - ] -} -############################################################################### diff --git a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/project.xml b/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/project.xml deleted file mode 100644 index be92381e05fc528d2fba5603365ee6df71b5b840..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/project.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - 1000 - - 30 - - 4096 - - diff --git a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.cpp b/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.cpp deleted file mode 100644 index 94f1a2011e928dfcd1019cf9093c3fcb78165862..0000000000000000000000000000000000000000 --- a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2022 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 "schemaquery_fuzzer.h" -#include "distributed_kv_data_manager.h" -#include "data_query.h" -#include "sys/stat.h" - -using namespace std; -using namespace OHOS; -using namespace DistributedKv; - -namespace OHOS { -constexpr const char *VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\"," - "\"SCHEMA_MODE\":\"STRICT\",\"SCHEMA_DEFINE\":{" - "\"name\":\"INTEGER, NOT NULL\"},\"SCHEMA_INDEXES\":[\"$.name\"}}"; -static DistributedKvDataManager g_kvManager; - -// Test 1: Open KvStore with fuzzed schema string. -void TestOpenSchemaStore001(std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = fuzzedString; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestOpenSchemaStore001_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -void ExecuteQuery(SingleKvStore* singleKvStorePtr, const DataQuery &query) -{ - if (singleKvStorePtr == nullptr) { - return; - } - std::vector results1; - singleKvStorePtr->GetEntries(query, results1); - Key prefix1; - std::vector results2; - singleKvStorePtr->GetEntries(prefix1, results2); - std::shared_ptr callback1; - singleKvStorePtr->GetResultSet(query, callback1); - singleKvStorePtr->CloseResultSet(callback1); - Key prefix2; - std::shared_ptr callback2; - singleKvStorePtr->GetResultSet(prefix2, callback2); - singleKvStorePtr->CloseResultSet(callback2); - int resultSize = 0; - singleKvStorePtr->GetCount(query, resultSize); -} - -// Test 2: Query EqualTo. -void TestQuerySchemaStore001(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, - bool fuzzedBoolean, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore001_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.EqualTo(fuzzedString, fuzzedInt); - query.And(); - query.EqualTo(fuzzedString, fuzzedLong); - query.Or(); - query.EqualTo(fuzzedString, fuzzedDouble); - query.And(); - query.EqualTo(fuzzedString, fuzzedBoolean); - query.Or(); - query.EqualTo(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 3: Query NotEqualTo. -void TestQuerySchemaStore002(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, - bool fuzzedBoolean, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore002_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.NotEqualTo(fuzzedString, fuzzedInt); - query.And(); - query.NotEqualTo(fuzzedString, fuzzedLong); - query.Or(); - query.NotEqualTo(fuzzedString, fuzzedDouble); - query.And(); - query.NotEqualTo(fuzzedString, fuzzedBoolean); - query.Or(); - query.NotEqualTo(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 4: Query GreaterThan. -void TestQuerySchemaStore003(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore003_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.GreaterThan(fuzzedString, fuzzedInt); - query.And(); - query.GreaterThan(fuzzedString, fuzzedLong); - query.Or(); - query.GreaterThan(fuzzedString, fuzzedDouble); - query.And(); - query.GreaterThan(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 5: Query LessThan. -void TestQuerySchemaStore004(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore004_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.LessThan(fuzzedString, fuzzedInt); - query.And(); - query.LessThan(fuzzedString, fuzzedLong); - query.Or(); - query.LessThan(fuzzedString, fuzzedDouble); - query.And(); - query.LessThan(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 6: Query GreaterThanOrEqualTo -void TestQuerySchemaStore005(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore005_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.GreaterThanOrEqualTo(fuzzedString, fuzzedInt); - query.And(); - query.GreaterThanOrEqualTo(fuzzedString, fuzzedLong); - query.Or(); - query.GreaterThanOrEqualTo(fuzzedString, fuzzedDouble); - query.And(); - query.GreaterThanOrEqualTo(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 7: Query LessThanOrEqualTo. -void TestQuerySchemaStore006(int fuzzedInt, int64_t fuzzedLong, double fuzzedDouble, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore006_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.LessThanOrEqualTo(fuzzedString, fuzzedInt); - query.And(); - query.LessThanOrEqualTo(fuzzedString, fuzzedLong); - query.Or(); - query.LessThanOrEqualTo(fuzzedString, fuzzedDouble); - query.And(); - query.LessThanOrEqualTo(fuzzedString, fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 8: Query IsNull. -void TestQuerySchemaStore007(std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore007_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.IsNull(fuzzedString); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 9: Query Like Unlike OrderByAsc OrderByDesc Limit. -void TestQuerySchemaStore008(int fuzzedInt, std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestQuerySchemaStore008_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - DataQuery query; - query.Reset(); - query.Like(fuzzedString, fuzzedString); - query.And(); - query.Unlike(fuzzedString, fuzzedString); - query.OrderByAsc(fuzzedString); - query.OrderByDesc(fuzzedString); - query.Limit(fuzzedInt, fuzzedInt); - ExecuteQuery(singleKvStorePtr.get(), query); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} - -// Test 10: Batch. -void TestBatch001(std::string &fuzzedString) -{ - std::shared_ptr singleKvStorePtr; - Options options = {.createIfMissing = true, .encrypt = true, .autoSync = true}; - options.schema = VALID_SCHEMA_STRICT_DEFINE; - options.area = EL1; - options.baseDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - AppId appId = {"schemaqueryfuzztest"}; - StoreId storeId = {"TestBatch001_storeId_fuzz"}; - g_kvManager.GetSingleKvStore(options, appId, storeId, singleKvStorePtr); - if (singleKvStorePtr == nullptr) { - return; - } - std::vector entries; - Entry entry1, entry2, entry3; - entry1.key = fuzzedString; - entry1.value = fuzzedString; - entry2.key = fuzzedString; - entry2.value = fuzzedString; - entry3.key = fuzzedString; - entry3.value = fuzzedString; - entries.push_back(entry1); - entries.push_back(entry2); - entries.push_back(entry3); - std::vector keys; - keys.push_back(fuzzedString); - singleKvStorePtr->PutBatch(entries); - singleKvStorePtr->DeleteBatch(keys); - g_kvManager.CloseAllKvStore(appId); - g_kvManager.DeleteAllKvStore(appId); -} -} - -/* Fuzzer entry point */ -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) -{ - // odd or even 2 - bool fuzzedBoolean = ((size % 2) == 0); - auto fuzzedInt = static_cast(size); - auto fuzzedLong = static_cast(size); - auto fuzzedDouble = static_cast(size); - std::string fuzzedString(reinterpret_cast(data), size); - - std::string storeDir = "/data/service/el1/public/database/schemaqueryfuzztest"; - mkdir(storeDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); - - OHOS::TestOpenSchemaStore001(fuzzedString); - OHOS::TestQuerySchemaStore001(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedBoolean, fuzzedString); - OHOS::TestQuerySchemaStore002(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedBoolean, fuzzedString); - OHOS::TestQuerySchemaStore003(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedString); - OHOS::TestQuerySchemaStore004(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedString); - OHOS::TestQuerySchemaStore005(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedString); - OHOS::TestQuerySchemaStore006(fuzzedInt, fuzzedLong, fuzzedDouble, fuzzedString); - OHOS::TestQuerySchemaStore007(fuzzedString); - OHOS::TestQuerySchemaStore008(fuzzedInt, fuzzedString); - OHOS::TestBatch001(fuzzedString); - - (void)remove("/data/service/el1/public/database/schemaqueryfuzztest/key"); - (void)remove("/data/service/el1/public/database/schemaqueryfuzztest/kvdb"); - (void)remove("/data/service/el1/public/database/schemaqueryfuzztest"); - return 0; -} \ No newline at end of file diff --git a/interface_sdk/api/@ohos.data.cloudData.d.ts b/interface_sdk/api/@ohos.data.cloudData.d.ts index d87363db36cc36c4b48f220090766589716da7b2..52224dbe4ad229aa1cadb55cdb2ac8ac9ef45239 100644 --- a/interface_sdk/api/@ohos.data.cloudData.d.ts +++ b/interface_sdk/api/@ohos.data.cloudData.d.ts @@ -14,11 +14,10 @@ */ import { AsyncCallback } from './@ohos.base'; -import relationalStore from "./@ohos.data.relationalStore"; declare namespace cloudData { /** - * Enumerates the types of the clear action. + * Describes the clear action type. * * @enum { number } * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -27,8 +26,7 @@ declare namespace cloudData { */ enum ClearAction { /** - * Clear cloud-related data only, which includes the cloud meta data and - * local cloud-related data. + * Indicates clearing cloud-related data only, which includes cloud meta data and cloud-related local data. * * @syscap SystemCapability.DistributedDataManager.CloudSync.Config * @systemapi @@ -37,7 +35,7 @@ declare namespace cloudData { CLEAR_CLOUD_INFO, /** - * Clear all cloud-related file data, which is synchronized with the cloud. + * Indicates clearing all cloud-related file data,which synchronized with the cloud. * * @syscap SystemCapability.DistributedDataManager.CloudSync.Config * @systemapi @@ -47,57 +45,7 @@ declare namespace cloudData { } /** - * ID of the event, which indicates the change of the data in the cloud. - * - * @constant - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @since 11 - */ - const DATA_CHANGE_EVENT_ID = "cloud_data_change"; - - /** - * Extra data for data change notification. - * - * @interface ExtraData - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @systemapi - * @since 11 - */ - interface ExtraData { - /** - * Event ID. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @systemapi - * @since 11 - */ - eventId: string; - - /** - * Extra data, which contains the following fields. - * { - * "accountId": "aaa", - * "bundleName": "com.bbb.xxx", - * "containerName": "alias", - * "databaseScopes": ["private", "shared"], - * "recordTypes": ["xxx", "yyy", "zzz"], - * "properties": { - * "key": "value" - * }, - * "keyId": "", - * "signV3": "" - * } - * accountId and bundleName are mandatory. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @systemapi - * @since 11 - */ - extraData: string; - } - - /** - * Provides methods to set cloud-device synchronization. + * Provides methods to set CloudSync config. * * @syscap SystemCapability.DistributedDataManager.CloudSync.Config * @systemapi @@ -108,19 +56,13 @@ declare namespace cloudData { * Enables the cloud function. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is - * a value obtained by hashing the cloud account ID. - * @param { { [bundleName:string]:boolean } } switches - Indicates switches - * of all applications. It overwrites the saved application switch information. - * If an application switch changes, the {@link changeAppCloudSwitch - * (accountId: string, bundleName: string, status: boolean)} method will be - * called to notify the data manager service. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { { [bundleName:string]:boolean } } switches - Indicates switches information of all applications. + * switches will overwrite the saved application switch information.If the specific application switch changes, + * the {@link changeAppCloudSwitch(accountId: string, bundleName: string, status: boolean)} method will notify the data manager service. + * @param { AsyncCallback } callback - the callback of enableCloud. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -137,18 +79,13 @@ declare namespace cloudData { * Enables the cloud function. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is - * a value obtained by hashing the cloud account ID. - * @param { { [bundleName:string]:boolean } } switches - Indicates switches - * of all applications. It overwrites the saved application switch information. - * If an application switch changes, the {@link changeAppCloudSwitch - * (accountId: string, bundleName: string, status: boolean)} method will be - * called to notify the data manager service. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { { [bundleName:string]:boolean } } switches - Indicates switches information of all applications. + * switches will overwrite the saved application switch information.If the specific application switch changes, + * the {@link changeAppCloudSwitch(accountId: string, bundleName: string, status: boolean)} method will notify the data manager service. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -161,14 +98,10 @@ declare namespace cloudData { * Disables the cloud function. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is - * a value obtained by hashing the cloud account ID. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { AsyncCallback } callback - the callback of disableCloud. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -181,13 +114,10 @@ declare namespace cloudData { * Disables the cloud function. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is - * a value obtained by hashing the cloud account ID. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -200,18 +130,12 @@ declare namespace cloudData { * Changes the cloud switch of a single application. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. * @param { string } bundleName - Indicates the name of application. - * @param { boolean } status - Indicates whether to enable cloud-device - * synchronization. The value true means to enable cloud-device - * synchronization; the value false means the opposite. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { boolean } status - Indicates the condition of cloud sync switch.true means the switch is on,false means switch is off. + * @param { AsyncCallback } callback - the callback of changeAppCloudSwitch. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -229,17 +153,12 @@ declare namespace cloudData { * Changes the cloud switch of a single application. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. * @param { string } bundleName - Indicates the name of application. - * @param { boolean } status - Indicates whether to enable cloud-device - * synchronization. The value true means to enable cloud-device - * synchronization; the value false means the opposite. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { boolean } status - Indicates the condition of cloud sync switch.true means the switch is on,false means switch is off. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -249,100 +168,48 @@ declare namespace cloudData { static changeAppCloudSwitch(accountId: string, bundleName: string, status: boolean): Promise; /** - * Notifies changes of the cloud records. + * notifies changes of the cloud records * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. * @param { string } bundleName - Indicates the name of application. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to report the data changes. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { AsyncCallback } callback - the callback of notifyDataChange. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 10 */ static notifyDataChange(accountId: string, bundleName: string, callback: AsyncCallback): void; /** - * Notifies changes of the cloud records. + * notifies changes of the cloud records * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. * @param { string } bundleName - Indicates the name of application. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 10 */ static notifyDataChange(accountId: string, bundleName: string): Promise; /** - * Notifies changes of the cloud records. + * deletes cloud information from local data. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { ExtraData } extInfo - Indicates the extra data for - * notification {@link ExtraData}. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to return the data changes. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @systemapi - * @since 11 - */ - static notifyDataChange(extInfo: ExtraData, callback: AsyncCallback): void; - - /** - * Notifies changes of the cloud records - * - * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { ExtraData } extInfo - Indicates the extra data for - * notification {@link ExtraData}. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config - * @systemapi - * - * @since 11 - */ - static notifyDataChange(extInfo: ExtraData): Promise; - - /** - * Clears cloud information from the local device. - * - * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. - * @param { { [bundleName: string]: ClearAction } } appActions - Indicates - * the clear operation to perform. - * @param { AsyncCallback } callback - Indicates the callback invoked - * to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { { [bundleName: string]: ClearAction } } appActions - Indicates the way in which the application data is to be cleared. + * @param { AsyncCallback } callback - the callback of clear. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -356,18 +223,14 @@ declare namespace cloudData { ): void; /** - * Clears cloud information from a local device. + * deletes cloud information from local data. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID, which is a value - * obtained by hashing the cloud account ID. - * @param { { [bundleName: string]: ClearAction } } appActions - Indicates - * the clear operation to perform. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing the information of specific opened cloud. + * @param { { [bundleName: string]: ClearAction } } appActions - Indicates the way in which the application data is to be cleared. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config @@ -376,611 +239,6 @@ declare namespace cloudData { */ static clear(accountId: string, appActions: { [bundleName: string]: ClearAction }): Promise; } - - /** - * Provides methods to implement cloud sharing. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - export namespace Sharing { - /** - * Enumerates the roles. - * - * @enum { number } - * @syscap systemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - enum Role { - /** - * Inviter of cloud sharing. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - ROLE_INVITER, - - /** - * Invitee of cloud sharing. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - ROLE_INVITEE - } - - /** - * Enumerates the statuses of sharing invitation. - * - * @enum { number } - * @syscap systemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - enum Status { - /** - * Unknown status. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - STATUS_UNKNOWN, - - /** - * Accept the sharing invitation. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - STATUS_ACCEPTED, - - /** - * Reject the sharing invitation. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - STATUS_REJECTED, - - /** - * Suspend the sharing process. - * - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - STATUS_SUSPENDED, - } - - /** - * Result interface. - * - * @interface Result - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @StageModelOnly - * @since 11 - */ - export interface Result { - /** - * Error code. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - code: number; - - /** - * The result value. - * - * @type { T } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - value: T; - } - - /** - * Privilege for the shared data. - * - * @interface Privilege - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - export interface Privilege { - /** - * Whether the participants can write the shared data. The value true - * means the participants can write the shared data; the value false - * means the opposite. - * - * @type { ?boolean } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - writeable?: boolean; - - /** - * Whether the participants can read the shared data. The value true - * means the participants can read the shared data; the value false - * means the opposite. - * - * @type { ?boolean } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - readable?: boolean; - - /** - * Whether the participants can create data. The value true - * means the participants can create data; the value false - * means the opposite. - * - * @type { ?boolean } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - creatable?: boolean; - - /** - * Whether the participants can delete the shared data. The value true - * means the participants can delete the shared data; the value false - * means the opposite. - * - * @type { ?boolean } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - deletable?: boolean; - - /** - * Whether the participants can share the data. The value true - * means the participants can share the data; the value false - * means the opposite. - * - * @type { ?boolean } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - shareable?: boolean; - } - - /** - * Participants in cloud sharing. - * - * @interface Participant - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - export interface Participant { - /** - * Identity of participant. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - identity: string; - - /** - * Role of the participant, which can be inviter or invitee. - * - * @type { ?Role } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - role?: Role; - - /** - * Status of the sharing invitation. - * - * @type { ?Status } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - status?: Status; - - /** - * Permissions for the shared data. - * - * @type { ?Privilege } - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - privilege?: Privilege; - } - - /** - * Allocates shared resources based on conditions, - * and shares data with the specified privilege to participants. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } storeId - Indicates relational store name. - * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. - * @param { Array } participants - Participants to share. - * @param { AsyncCallback } callback - Indicates the - * callback invoked to return the {@link relationalStore.ResultSet}. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function allocResourceAndShare( - storeId: string, - predicates: relationalStore.RdbPredicates, - participants: Array, - callback: AsyncCallback - ): void; - - /** - * Allocates shared resources based on conditions, - * and shares data with the specified privilege to participants. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } storeId - Indicates relational store name. - * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. - * @param { Array } columns - Columns to be shared. - * @param { Array } participants - Participants to share. - * @param { AsyncCallback } callback - Indicates the - * callback invoked to return the {@link relationalStore.ResultSet}. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function allocResourceAndShare( - storeId: string, - predicates: relationalStore.RdbPredicates, - participants: Array, - columns: Array, - callback: AsyncCallback - ): void; - - /** - * Allocates shared resources based on conditions, - * and shares data with the specified privilege to participants. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } storeId - Indicates relational store name. - * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. - * @param { Array } participants - Participants to share. - * @param { Array } [columns] - Columns to be shared. - * @param { Promise } - Promise used to return {@link relationalStore.ResultSet}. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function allocResourceAndShare( - storeId: string, - predicates: relationalStore.RdbPredicates, - participants: Array, - columns?: Array - ): Promise; - - /** - * Shares data with the specified privilege to participants. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * involved in the data sharing. - * @param { AsyncCallback>> } callback - Indicates the - * callback invoked to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function share( - sharingRes: string, - participants: Array, - callback: AsyncCallback>> - ): void; - - /** - * Shares data with the specified privilege to participants. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * involved in the data sharing. - * @Returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function share(sharingRes: string, participants: Array): Promise>>; - - /** - * Unshares data. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * involved. - * @param { AsyncCallback>> } callback - Indicates the callback invoked - * to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function unshare( - sharingRes: string, - participants: Array, - callback: AsyncCallback>> - ): void; - - /** - * Unshares data. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * involved. - * @Returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function unshare(sharingRes: string, participants: Array): Promise>>; - - /** - * Exit sharing. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { AsyncCallback } callback - The callback of exit. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function exit(sharingRes: string, callback: AsyncCallback): void; - - /** - * Exit sharing. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @Returns { Promise } - The promise returned by the function. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function exit(sharingRes: string): Promise; - - /** - * Changes the permissions for the shared data. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * whose permissions are to be changed. - * @param { AsyncCallback>> } callback - Indicates the - * callback invoked to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function changePrivilege( - sharingRes: string, - participants: Array, - callback: AsyncCallback>> - ): void; - - /** - * Changes the permissions for the shared data. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the participants - * whose permissions are to be changed. - * @Returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function changePrivilege( - sharingRes: string, - participants: Array - ): Promise>>; - - /** - * Queries the participants based on the specified shared data. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { AsyncCallback>> } callback - Indicates the - * callback invoked to return the participants obtained. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function queryParticipants(sharingRes: string, callback: AsyncCallback>>): void; - - /** - * Queries the participants based on the specified shared data.. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @Returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function queryParticipants(sharingRes: string): Promise>>; - - /** - * Confirms the invitation of cloud sharing. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } invitationCode - Indicates the invitation code. - * @param { Status } status - Indicates the status of invitation. - * @param { AsyncCallback> } callback - Indicates the callback - * invoked to return the sharing resource. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function confirmInvitation(invitationCode: string, status: Status, callback: AsyncCallback>): void; - - /** - * Confirms the invitation of cloud sharing. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } invitationCode - Indicates the invitation code. - * @param { Status } status - Indicates the status of invitation. - * @Returns { Promise> } - Promise used to return the sharing resource. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function confirmInvitation(invitationCode: string, status: Status): Promise>; - - /** - * Changes confirmation of shared record. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Status } status - Indicates the status of invitation. - * @param { AsyncCallback } callback - Indicates the callback. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function changeConfirmation(sharingRes: string, status: Status, callback: AsyncCallback): void; - - /** - * Changes confirmation of shared record. - * - * @permission ohos.permission.CLOUDDATA_SHARING - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Status } status - Indicates the status of invitation. - * @Returns { Promise } - The promise returned by the function. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudData.Sharing - * @systemapi - * @since 11 - */ - function changeConfirmation(sharingRes: string, status: Status): Promise; - } } export default cloudData; diff --git a/interface_sdk/api/@ohos.data.distributedDataObject.d.ts b/interface_sdk/api/@ohos.data.distributedDataObject.d.ts index d43a4105f533b44a7f60d0e1090d7301c9d6b7d9..f0cdbe67d0790fbe0287c8115d310212c80322a2 100644 --- a/interface_sdk/api/@ohos.data.distributedDataObject.d.ts +++ b/interface_sdk/api/@ohos.data.distributedDataObject.d.ts @@ -137,8 +137,8 @@ declare namespace distributedDataObject { /** * On watch of change * - * @param { 'change' } type - Event type, fixed as' change ', indicates data change. - * @param { Callback<{ sessionId: string, fields: Array }> } callback + * @param { 'change' } type - Event type, fixed as 'change', indicates data change. + * @param { Function } callback * Indicates the observer of object data changed. * {string} sessionId - The sessionId of the changed object. * {Array} fields - Changed data. @@ -147,13 +147,13 @@ declare namespace distributedDataObject { * @deprecated since 9 * @useinstead ohos.distributedDataObject.DataObject.on */ - on(type: 'change', callback: Callback<{ sessionId: string, fields: Array }>): void; + on(type: 'change', callback: (sessionId: string, fields: Array) => void): void; /** * Off watch of change * - * @param { 'change' } type - Event type, fixed as' change ', indicates data change. - * @param { Callback<{ sessionId: string, fields: Array }> } callback + * @param { 'change' } type - Event type, fixed as 'change', indicates data change. + * @param { Function } callback * Indicates the observer of object data changed. * {string} sessionId - The sessionId of the changed object. * {Array} fields - Changed data. @@ -163,13 +163,13 @@ declare namespace distributedDataObject { * @deprecated since 9 * @useinstead ohos.distributedDataObject.DataObject.off */ - off(type: 'change', callback?: Callback<{ sessionId: string, fields: Array }>): void; + off(type: 'change', callback?: (sessionId: string, fields: Array) => void): void; /** * On watch of status * - * @param { 'status' } type - Event type, fixed as' status', indicates the online and offline of the object. - * @param { Callback<{ sessionId: string, networkId: string, status: 'online' | 'offline' }> } callback + * @param { 'status' } type - Event type, fixed as 'status', indicates the online and offline of the object. + * @param { Function } callback * Indicates the observer of object status changed. * {string} sessionId - The sessionId of the changed object. * {string} networkId - NetworkId of the changed device. @@ -183,14 +183,14 @@ declare namespace distributedDataObject { */ on( type: 'status', - callback: Callback<{ sessionId: string, networkId: string, status: 'online' | 'offline' }> + callback: (sessionId: string, networkId: string, status: 'online' | 'offline' ) => void ): void; /** * Off watch of status * - * @param { 'status' } type - Event type, fixed as' status', indicates the online and offline of the object. - * @param { Callback<{ sessionId: string, deviceId: string, status: 'online' | 'offline' }> } callback + * @param { 'status' } type - Event type, fixed as 'status', indicates the online and offline of the object. + * @param { Function } callback * Indicates the observer of object status changed. * {string} sessionId - The sessionId of the changed object. * {string} networkId - NetworkId of the changed device. @@ -205,7 +205,7 @@ declare namespace distributedDataObject { */ off( type: 'status', - callback?: Callback<{ sessionId: string, deviceId: string, status: 'online' | 'offline' }> + callback?: (sessionId: string, networkId: string, status: 'online' | 'offline' ) => void ): void; } @@ -262,8 +262,9 @@ declare namespace distributedDataObject { /** * On watch of change. * - * @param { 'change' } type - event type, fixed as' change ', indicates data change. - * @param { Callback<{ sessionId: string, fields: Array }> } callback + * @param { 'change' } type - event type, fixed as 'change', indicates data change. + * @param { Function } callback + * * indicates the observer of object data changed. * {string} sessionId - the sessionId of the changed object. * {Array} fields - changed data. @@ -272,13 +273,13 @@ declare namespace distributedDataObject { * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject * @since 9 */ - on(type: 'change', callback: Callback<{ sessionId: string, fields: Array }>): void; + on(type: 'change', callback: (sessionId: string, fields: Array) => void ): void; /** * Off watch of change. * - * @param { 'change' } type - Event type, fixed as' change ', indicates data change. - * @param { Callback<{ sessionId: string, fields: Array }> } callback + * @param { 'change' } type - Event type, fixed as 'change', indicates data change. + * @param { Function } callback * indicates the observer of object data changed. * {string} sessionId - The sessionId of the changed object. * {Array} fields - Changed data. @@ -287,13 +288,13 @@ declare namespace distributedDataObject { * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject * @since 9 */ - off(type: 'change', callback?: Callback<{ sessionId: string, fields: Array }>): void; + off(type: 'change', callback?: (sessionId: string, fields: Array) => void ): void; /** * On watch of status. * - * @param { 'status' } type - Event type, fixed as' status', indicates the online and offline of the object. - * @param { Callback<{ sessionId: string, networkId: string, status: 'online' | 'offline' }> } callback + * @param { 'status' } type - Event type, fixed as 'status', indicates the online and offline of the object. + * @param { Function } callback * indicates the observer of object status changed. * {string} sessionId - The sessionId of the changed object. * {string} networkId - NetworkId of the changed device. @@ -307,14 +308,14 @@ declare namespace distributedDataObject { */ on( type: 'status', - callback: Callback<{ sessionId: string, networkId: string, status: 'online' | 'offline' }> + callback: (sessionId: string, networkId: string, status: 'online' | 'offline' ) => void ): void; /** * Off watch of status. * - * @param { 'status' } type - Event type, fixed as' status', indicates the online and offline of the object. - * @param { Callback<{ sessionId: string, deviceId: string, status: 'online' | 'offline' }> } callback + * @param { 'status' } type - Event type, fixed as 'status', indicates the online and offline of the object. + * @param { Function } callback * Indicates the observer of object status changed. * {string} sessionId - The sessionId of the changed object. * {string} networkId - NetworkId of the changed device. @@ -328,7 +329,7 @@ declare namespace distributedDataObject { */ off( type: 'status', - callback?: Callback<{ sessionId: string, deviceId: string, status: 'online' | 'offline' }> + callback?: (sessionId: string, networkId: string, status: 'online' | 'offline' ) => void ): void; /** diff --git a/interface_sdk/api/@ohos.data.preferences.d.ts b/interface_sdk/api/@ohos.data.preferences.d.ts index c87652e13ef1d96914832a30266f5142884ab315..8d538eae8d38a0e9150334fb395a9bb3e9d98d10 100644 --- a/interface_sdk/api/@ohos.data.preferences.d.ts +++ b/interface_sdk/api/@ohos.data.preferences.d.ts @@ -912,25 +912,25 @@ declare namespace preferences { * Registers an observer to listen for the change of a {@link Preferences} object. * * @param { 'change' } type - Indicates the callback when preferences changes. - * @param { Callback<{ key: string }> } callback - Indicates the callback function. + * @param { Function } callback - Indicates the callback function. * @throws { BusinessError } 401 - Parameter error. * @syscap SystemCapability.DistributedDataManager.Preferences.Core * @crossplatform * @since 10 */ - on(type: 'change', callback: Callback<{ key: string }>): void; + on(type: 'change', callback: (key: string) => void): void; /** * Registers an observer to listen for the change of a {@link Preferences} object. * * @param { 'multiProcessChange' } type - Indicates the callback when preferences changed in multiple processes. - * @param { Callback<{ key: string }> } callback - Indicates the callback function. + * @param { Function } callback - Indicates the callback function. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 15500019 - Failed to obtain subscription service. * @syscap SystemCapability.DistributedDataManager.Preferences.Core * @since 10 */ - on(type: 'multiProcessChange', callback: Callback<{ key: string }>): void; + on(type: 'multiProcessChange', callback: (key: string) => void): void; /** * Unregisters an existing observer. @@ -945,24 +945,24 @@ declare namespace preferences { * Unregisters an existing observer. * * @param { 'change' } type - Indicates the callback when preferences changes. - * @param { Callback<{ key: string }> } callback - Indicates the callback function. + * @param { Function } callback - Indicates the callback function. * @throws { BusinessError } 401 - Parameter error. * @syscap SystemCapability.DistributedDataManager.Preferences.Core * @crossplatform * @since 10 */ - off(type: 'change', callback?: Callback<{ key: string }>): void; + off(type: 'change', callback?: (key: string) => void): void; /** * Unregisters an existing observer. * * @param { 'multiProcessChange' } type - Indicates the callback when preferences changed in multiple processes. - * @param { Callback<{ key: string }> } callback - Indicates the callback function. + * @param { Function } callback - Indicates the callback function. * @throws { BusinessError } 401 - Parameter error. * @syscap SystemCapability.DistributedDataManager.Preferences.Core * @since 10 */ - off(type: 'multiProcessChange', callback?: Callback<{ key: string }>): void; + off(type: 'multiProcessChange', callback?: (key: string) => void): void; } } diff --git a/interface_sdk/api/@ohos.data.relationalStore.d.ts b/interface_sdk/api/@ohos.data.relationalStore.d.ts index e43ff5cd40bd3ce7d6a71329434899032e7a7067..559ca21cec53f5476dd77a1206dd0b3b57171372 100644 --- a/interface_sdk/api/@ohos.data.relationalStore.d.ts +++ b/interface_sdk/api/@ohos.data.relationalStore.d.ts @@ -291,12 +291,14 @@ declare namespace relationalStore { dataGroupId?: string; /** - * Specifies whether retain data that deleted in cloud, default false. + * Specifies the directory relative to the database directory obtained from context * + * @type { ?string } * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @crossplatform * @since 11 */ - retainData?: boolean; + customDir?: string; } /** @@ -740,12 +742,6 @@ declare namespace relationalStore { DISTRIBUTED_CLOUD } - interface ColumnVector { - originTable: string; - endTable: string; - fields: { [origin: string]: string } - } - /** * Manages the distributed configuration of the table. * @@ -761,8 +757,6 @@ declare namespace relationalStore { * @since 10 */ autoSync: boolean; - - references?: Array; } /** @@ -829,39 +823,6 @@ declare namespace relationalStore { ON_CONFLICT_REPLACE = 5 } - /** - * Describes the sources to modify data. - * - * @enum { number } - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - enum Location { - /** - * Indicates local operation modify the data. - * - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - LOCAL, - - /** - * Indicates cloud operation modify the data. - * - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - CLOUD, - - /** - * Indicates remote operation modify the data. - * - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - REMOTE, - } - /** * Manages relational database configurations. * @@ -876,28 +837,6 @@ declare namespace relationalStore { * @since 10 */ class RdbPredicates { - /** - * The CURSOR field name {#_cursor}. - * - * If not specify local field, cursor would acts on all {@link Location}. - * - * @readonly - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - readonly CURSOR_FIELD: string; - - /** - * The LOCATION field name {#_location}. - * - * Location field for cursor query, value detail see {@link Location}. - * - * @readonly - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - readonly LOCATION_FIELD: string; - /** * A parameterized constructor used to create a RdbPredicates instance. * @@ -2809,100 +2748,6 @@ declare namespace relationalStore { primaryKeys: PRIKeyType[], callback: AsyncCallback ): void; - - /** - * Cleans the retained data deleted in cloud. - * - * @param { string } table - Indicates the name of the table to check. - * @param { AsyncCallback } callback - The callback of clean. - * @throws { BusinessError } 801 - Capability not supported. - * @throws { BusinessError } 14800000 - Inner error. - * @throws { BusinessError } 401 - Parameter error. - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - clean(table: string, callback: AsyncCallback): void; - - /** - * Cleans the retained data deleted in cloud. - * - * @param { string } table - Indicates the name of the table to check. - * @returns { Promise } -The promise returned by the function. - * @throws { BusinessError } 801 - Capability not supported. - * @throws { BusinessError } 14800000 - Inner error. - * @throws { BusinessError } 401 - Parameter error. - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @since 11 - */ - clean(table: string): Promise; - - /** - * SHARING_RESOURCE_FIELD. - * - * @readonly - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @systemapi - * @since 11 - */ - readonly SHARING_RESOURCE_FIELD: string; - - /** - * SHARING_RESULT_FIELD. - * - * @readonly - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @systemapi - * @since 11 - */ - readonly SHARING_RESULT_FIELD: string; - - /** - * Obtains sharing resource of rows corresponding to the predicates. - * - * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. - * @param { AsyncCallback } callback - The callback of querySharingResource. - * {@link ResultSet} is query result. - * @throws { BusinessError } 801 - Capability not supported. - * @throws { BusinessError } 14800000 - Inner error. - * @throws { BusinessError } 401 - Parameter error. - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @systemapi - * @since 11 - */ - querySharingResource(predicates: RdbPredicates, callback: AsyncCallback): void; - - /** - * Obtains sharing resource of rows corresponding to the predicates. - * - * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. - * @param { Array } columns - The specified columns to query. - * @param { AsyncCallback } callback - The callback of querySharingResource. - * {@link ResultSet} is query result. - * @throws { BusinessError } 801 - Capability not supported. - * @throws { BusinessError } 14800000 - Inner error. - * @throws { BusinessError } 401 - Parameter error. - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @systemapi - * @since 11 - */ - querySharingResource(predicates: RdbPredicates, columns: Array, callback: AsyncCallback): void; - - /** - * Obtains sharing resource of rows corresponding to the predicates. - * - * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. - * @param { Array } columns? - The specified columns to query. - * @returns { Promise } -The promise returned by the function. - * {@link ResultSet} is query result. - * @throws { BusinessError } 801 - Capability not supported. - * @throws { BusinessError } 14800000 - Inner error. - * @throws { BusinessError } 401 - Parameter error. - * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core - * @systemapi - * @since 11 - */ - querySharingResource(predicates: RdbPredicates, columns?: Array): Promise; - /** * Executes a SQL statement that contains specified parameters but returns no value. * @@ -3332,6 +3177,47 @@ declare namespace relationalStore { */ cloudSync(mode: SyncMode, tables: string[], progress: Callback): Promise; + /** + * Sync data to cloud. + * + * @permission ohos.permission.DISTRIBUTED_DATASYNC + * @param { SyncMode } mode - indicates the database synchronization mode. + * @param { RdbPredicates } predicates - The specified sync condition by the instance object of {@link RdbPredicates}. + * @param { Callback } progress - the specified sync condition by the instance object of {@link ProgressDetails}. + * @param { AsyncCallback } callback - The callback of cloudSync. + * @throws { BusinessError } 401 - if the parameter type is incorrect. + * @throws { BusinessError } 202 - if permission verification failed, application does not have permission ohos.permission.DISTRIBUTED_DATASYNC + * or application which is not a system application uses system API. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + cloudSync( + mode: SyncMode, + predicates: RdbPredicates, + progress: Callback, + callback: AsyncCallback + ): void; + + /** + * Sync data to cloud. + * + * @permission ohos.permission.DISTRIBUTED_DATASYNC + * @param { SyncMode } mode - indicates the database synchronization mode. + * @param { RdbPredicates } predicates - The specified sync condition by the instance object of {@link RdbPredicates}. + * @param { Callback } progress - the specified sync condition by the instance object of {@link ProgressDetails}. + * @returns { Promise } : The promise returned by the function. + * @throws { BusinessError } 401 - if the parameter type is incorrect. + * @throws { BusinessError } 202 - if permission verification failed, application does not have permission ohos.permission.DISTRIBUTED_DATASYNC + * or application which is not a system application uses system API. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + cloudSync(mode: SyncMode, predicates: RdbPredicates, progress: Callback): Promise; + /** * Queries remote data in the database based on specified conditions before Synchronizing Data. * @@ -3418,6 +3304,18 @@ declare namespace relationalStore { */ on(event: string, interProcess: boolean, observer: Callback): void; + /** + * Register an automatic synchronization callback to the database. + * + * @param { 'autoSyncProgress' } event - Indicates the event must be string 'autoSyncProgress'. + * @param { Callback } progress - the specified sync condition by the instance object of {@link ProgressDetails}. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 11 + */ + on(event: 'autoSyncProgress', progress: Callback): void; + /** * Remove specified observer of specified type from the database. * @@ -3467,6 +3365,18 @@ declare namespace relationalStore { */ off(event: string, interProcess: boolean, observer?: Callback): void; + /** + * Unregister the database auto synchronization callback. + * + * @param { 'autoSyncProgress' } event - indicates the event must be string 'autoSyncProgress'. + * @param { Callback } progress - the specified sync condition by the instance object of {@link ProgressDetails}. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 11 + */ + off(event: 'autoSyncProgress', progress?: Callback): void; + /** * Notifies the registered observers of a change to the data resource specified by Uri. * @@ -3553,6 +3463,7 @@ declare namespace relationalStore { /** * Deletes the database with a specified name. + * When specify custom directory, this function should not be called. * * @param { Context } context - Indicates the context of application or capability. * @param { string } name - Indicates the database name. @@ -3565,6 +3476,7 @@ declare namespace relationalStore { */ /** * Deletes the database with a specified name. + * When specify custom directory, this function should not be called. * * @param { Context } context - Indicates the context of application or capability. * @param { string } name - Indicates the database name. @@ -3580,6 +3492,7 @@ declare namespace relationalStore { /** * Deletes the database with a specified store config. + * When specify custom directory, this function should be called. * * @param { Context } context - Indicates the context of an application or ability. * @param { StoreConfig } config - Indicates the {@link StoreConfig} configuration of the database related to this RDB store. @@ -3597,6 +3510,7 @@ declare namespace relationalStore { /** * Deletes the database with a specified name. + * When specify custom directory, this function should not be called. * * @param { Context } context - Indicates the context of application or capability. * @param { string } name - Indicates the database name. @@ -3609,6 +3523,7 @@ declare namespace relationalStore { */ /** * Deletes the database with a specified name. + * When specify custom directory, this function should not be called. * * @param { Context } context - Indicates the context of application or capability. * @param { string } name - Indicates the database name. @@ -3624,6 +3539,7 @@ declare namespace relationalStore { /** * Deletes the database with a specified store config. + * When specify custom directory, this function should be called. * * @param { Context } context - Indicates the context of an application or ability. * @param { StoreConfig } config - Indicates the {@link StoreConfig} configuration of the database related to this RDB store. diff --git a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts index 02cf2249d33bfb2a788e457b208fc466737abfc8..c3141f7af3031b46b0f1e850324cfcd9d82eb46a 100644 --- a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts +++ b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts @@ -14,7 +14,7 @@ */ /** - * Provide methods for uniform data type definition and query. + * Provides methods for uniform data type definition and query. * * @namespace uniformTypeDescriptor * @syscap SystemCapability.DistributedDataManager.UDMF.Core @@ -22,7 +22,7 @@ */ declare namespace uniformTypeDescriptor { /** - * The data type supported by uniform type descriptor + * Uniform data type IDs. * * @enum { string } * @syscap SystemCapability.DistributedDataManager.UDMF.Core @@ -30,90 +30,791 @@ declare namespace uniformTypeDescriptor { */ enum UniformDataType { /** - * Indicate the data type is text + * Text data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ TEXT = 'general.text', + /** - * Indicate the data type is plain text + * Plain text data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ PLAIN_TEXT = 'general.plain-text', + /** - * Indicate the data type is hyperlink + * HTML data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ - HYPERLINK = 'general.hyperlink', + HTML = 'general.html', + /** - * Indicate the data type is html + * Hyperlink data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ - HTML = 'general.html', + HYPERLINK = 'general.hyperlink', + /** - * Indicate the data type is File + * XML(Extensible Markup Language) data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core - * @since 10 + * @since 11 */ - FILE = 'general.file', + XML = 'general.xml', + + /** + * Source code data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + SOURCE_CODE = 'general.source-code', + + /** + * Script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + SCRIPT = 'general.script', + + /** + * Shell script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + SHELL_SCRIPT = 'general.shell-script', + + /** + * C-shell script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + CSH_SCRIPT = 'general.csh-script', + + /** + * Perl script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PERL_SCRIPT = 'general.perl-script', + + /** + * PHP script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PHP_SCRIPT = 'general.php-script', + + /** + * Python script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PYTHON_SCRIPT = 'general.python-script', + + /** + * Ruby script data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + RUBY_SCRIPT = 'general.ruby-script', + + /** + * TypeScript data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + TYPE_SCRIPT = 'general.type-script', + + /** + * JavaScript data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + JAVA_SCRIPT = 'general.java-script', + + /** + * C header data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + C_HEADER = 'general.c-header', + + /** + * C source code data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + C_SOURCE = 'general.c-source', + + /** + * C++ header data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + C_PLUS_PLUS_HEADER = 'general.c-plus-plus-header', + + /** + * C++ source code data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + C_PLUS_PLUS_SOURCE = 'general.c-plus-plus-source', + + /** + * Java source code data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + JAVA_SOURCE = 'general.java-source', + + /** + * Ebook data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + EBOOK = 'general.ebook', + + /** + * EPUB ebook file format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + EPUB = 'general.epub', + + /** + * AZW ebook file format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AZW = 'com.amazon.azw', + + /** + * AZW3 ebook file format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AZW3 = 'com.amazon.azw3', + + /** + * KFX ebook file format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + KFX = 'com.amazon.kfx', + + /** + * MOBI ebook file format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MOBI = 'com.amazon.mobi', + + /** + * Media data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MEDIA = 'general.media', + /** - * Indicate the data type is image + * Image data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ IMAGE = 'general.image', + + /** + * JPEG image format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + JPEG = 'general.jpeg', + + /** + * PNG image format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PNG = 'general.png', + + /** + * Raw image format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + RAW_IMAGE = 'general.raw-image', + + /** + * TIFF image format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + TIFF = 'general.tiff', + + /** + * Windows bitmap image data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + BMP = 'com.microsoft.bmp', + + /** + * Windows icon data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + ICO = 'com.microsoft.ico', + + /** + * Adobe Photoshop document data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PHOTOSHOP_IMAGE = 'com.adobe.photoshop-image', + + /** + * Adobe Illustrator document data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AI_IMAGE = 'com.adobe.illustrator.ai-image', + + /** + * Microsoft Word data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WORD_DOC = 'com.microsoft.word.doc', + + /** + * Microsoft Excel data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + EXCEL = 'com.microsoft.excel.xls', + + /** + * Microsoft PowerPoint presentation data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PPT = 'com.microsoft.powerpoint.ppt', + + /** + * PDF data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PDF = 'com.adobe.pdf', + + /** + * PostScript data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + POSTSCRIPT = 'com.adobe.postscript', + /** - * Indicate the data type is video + * Encapsulated PostScript data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + ENCAPSULATED_POSTSCRIPT = 'com.adobe.encapsulated-postscript', + + /** + * Video data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ VIDEO = 'general.video', + /** - * Indicate the data type is audio + * AVI video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AVI = 'general.avi', + + /** + * MPEG video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MPEG = 'general.mpeg', + + /** + * MPEG4 video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MPEG4 = 'general.mpeg-4', + + /** + * 3GPP video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + VIDEO_3GPP = 'general.3gpp', + + /** + * 3GPP2 video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + VIDEO_3GPP2 = 'general.3gpp2', + + /** + * Windows WM video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WM = 'com.microsoft.windows-media-wm', + + /** + * Windows WMV video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WMV = 'com.microsoft.windows-media-wmv', + + /** + * Windows WMP video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WMP = 'com.microsoft.windows-media-wmp', + + /** + * Audio data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ AUDIO = 'general.audio', + + /** + * AAC audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AAC = 'general.aac', + + /** + * AIFF audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + AIFF = 'general.aiff', + + /** + * ALAC audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + ALAC = 'general.alac', + + /** + * FLAC audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + FLAC = 'general.flac', + + /** + * MP3 audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MP3 = 'general.mp3', + + /** + * OGG audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + OGG = 'general.ogg', + + /** + * PCM audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + PCM = 'general.pcm', + + /** + * Windows WMA audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WMA = 'com.microsoft.windows-media-wma', + + /** + * Waveform audio format data type created by Microsoft. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WAVEFORM_AUDIO = 'com.microsoft.waveform-audio', + + /** + * Windows WMX audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WMX = 'com.microsoft.windows-media-wmx', + + /** + * Windows WVX audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WVX = 'com.microsoft.windows-media-wvx', + /** - * Indicate the data type is Folder + * Windows WAX audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + WINDOWS_MEDIA_WAX = 'com.microsoft.windows-media-wax', + + /** + * File data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 10 + */ + FILE = 'general.file', + + /** + * Directory data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + DIRECTORY = 'general.directory', + + /** + * Folder data type. * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ FOLDER = 'general.folder', + + /** + * Symlink data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + SYMLINK = 'general.symlink', + + /** + * Archive file data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + ARCHIVE = 'general.archive', + /** - * Indicate the data type is OpenHarmony system defined form(the data is provided and bound to OpenHarmony system) + * Bzip2 archive file data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + BZ2_ARCHIVE = 'general.bz2-archive', + + /** + * Disk image archive file data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + DISK_IMAGE = 'general.disk-image', + + /** + * Tar archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + TAR_ARCHIVE = 'general.tar-archive', + + /** + * Zip archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + ZIP_ARCHIVE = 'general.zip-archive', + + /** + * Java archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + JAVA_ARCHIVE = 'com.sun.java-archive', + + /** + * GNU archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + GNU_TAR_ARCHIVE = 'org.gnu.gnu-tar-archive', + + /** + * Gzip archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + GNU_ZIP_ARCHIVE = 'org.gnu.gnu-zip-archive', + + /** + * Gzip tar archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + GNU_ZIP_TAR_ARCHIVE = 'org.gnu.gnu-zip-tar-archive', + + /** + * Calendar data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + CALENDAR = 'general.calendar', + + /** + * Contact data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + CONTACT = 'general.contact', + + /** + * Database data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + DATABASE = 'general.database', + + /** + * Message data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + MESSAGE = 'general.message', + + /** + * A file format data type stand for electronic business card. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + VCARD = 'general.vcard', + + /** + * Navigation data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + NAVIGATION = 'general.navigation', + + /** + * Location data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + LOCATION = 'general.location', + + /** + * OpenHarmony system defined form data type(the data is provided and bound to OpenHarmony system). * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ OPENHARMONY_FORM = 'openharmony.form', + /** - * Indicate the data type is OpenHarmony system defined app item(the data is provided and bound to OpenHarmony system) + * OpenHarmony system defined app item data type(the data is provided and bound to OpenHarmony system). * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ OPENHARMONY_APP_ITEM = 'openharmony.app-item', + /** - * Indicate the data type is OpenHarmony system defined pixel map(the data is provided and bound to OpenHarmony system) + * OpenHarmony system defined pixel map data type(the data is provided and bound to OpenHarmony system). * * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 10 */ - OPENHARMONY_PIXEL_MAP = 'openharmony.pixel-map' + OPENHARMONY_PIXEL_MAP = 'openharmony.pixel-map', + + /** + * OpenHarmony system defined atomic service data type(the data is provided and bound to OpenHarmony system). + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + OPENHARMONY_ATOMIC_SERVICE = 'openharmony.atomic-service' + } + + /** + * Class describing the uniform data type defined in the {@code UniformDataType}, which consists of attributes and + *
methods describing the uniform data type and its relationships to other uniform data types. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + class TypeDescriptor { + /** + * Type ID of the uniform data type, which corresponds to the enum string in the {@code UniformDataType}. + * + * @type { string } + * @readonly + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + readonly typeId: string; + + /** + * Uniform data type IDs that the uniform data type belongs to. + * + * @type { Array } + * @readonly + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + readonly belongingToTypes: Array; + + /** + * A textual description for the uniform data type. + * + * @type { string } + * @readonly + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + readonly description: string; + + /** + * Reference URL for the uniform data type, which describes the detail information of the type. + * + * @type { string } + * @readonly + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + readonly referenceURL: string; + + /** + * Default icon file path for the uniform data type. + * + * @type { string } + * @readonly + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + readonly iconFile: string; + + /** + * Checks whether the uniform type descriptor is equal to the given uniform type descriptor. + * + * @param { TypeDescriptor } typeDescriptor - A uniform type descriptor to be compared. + * @returns { boolean } Returns true if the type descriptor is equal to the given type descriptor, else false. + * @throws { BusinessError } 401 - Parameter error. + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + equals(typeDescriptor: TypeDescriptor): boolean; } + + /** + * Queries and returns the uniform type descriptor by the given uniform data type ID. + * + * @param { string } typeId - Uniform data type ID. + * @returns { TypeDescriptor } Returns the uniform type descriptor corresponding to the uniform data type ID or null + *
if the uniform data type does not exist. + * @throws { BusinessError } 401 - Parameter error. + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 11 + */ + function getTypeDescriptor(typeId: string): TypeDescriptor; } export default uniformTypeDescriptor; diff --git a/kv_store/BUILD.gn b/kv_store/BUILD.gn index 75794e338baaeb94648b058b594093dff58cfbe9..61726f986b996e690fe53d92610f787c84e0b359 100644 --- a/kv_store/BUILD.gn +++ b/kv_store/BUILD.gn @@ -27,6 +27,10 @@ group("build_native_test") { "frameworks/libs/distributeddb/test:unittest", "frameworks/libs/distributeddb/test/moduletest:moduletest", ] + if (!defined(global_parts_info.distributeddatamgr_kv_store_lite)) { + deps += + [ "frameworks/libs/distributeddb/gaussdb_rd/test/unittest:unittest" ] + } } ############################################################################### diff --git a/kv_store/CMakeLists.txt b/kv_store/CMakeLists.txt index 51b40866a89ed8d18e36d27d3f82570c33128c17..00a795362abb62e6e2cc3266f84955982272666d 100644 --- a/kv_store/CMakeLists.txt +++ b/kv_store/CMakeLists.txt @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 3.11.2) project(kv_store) add_subdirectory(frameworks/libs) +add_subdirectory(frameworks/libs/distributeddb/gaussdb_rd) add_subdirectory(frameworks) \ No newline at end of file diff --git a/kv_store/CODEOWNERS b/kv_store/CODEOWNERS index 91b62a26f8bd3a428825ae3eb1d05b2937c4ea4e..71c2f7c92dd90f314b1fd28f1fae26e4cfb6cad5 100644 --- a/kv_store/CODEOWNERS +++ b/kv_store/CODEOWNERS @@ -12,8 +12,8 @@ # limitations under the License. # any change to -# frameworks/innerkitsimpl/distributeddatafwk/include/distributeddata_ipc_interface_code.h +# frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h # frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h # needs to be reviewed by @leonchan5 -frameworks/innerkitsimpl/distributeddatafwk/include/distributeddata_ipc_interface_code.h @leonchan5 +frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h @leonchan5 frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h @leonchan5 \ No newline at end of file diff --git a/kv_store/bundle.json b/kv_store/bundle.json index d6a01405778b7f5ebb4a773fb501af85f91124f2..854af90eeb88840d1cf64648af5c9b42364f52e8 100644 --- a/kv_store/bundle.json +++ b/kv_store/bundle.json @@ -48,6 +48,8 @@ "hisysevent_config": [], "deps": { "third_party": [ + "bounds_checking_function", + "cJSON", "jsoncpp", "libuv", "openssl", @@ -100,7 +102,11 @@ "types.h", "visibility.h", "data_query.h", - "store_errno.h" + "store_errno.h", + "executor.h", + "executor_pool.h", + "pool.h", + "priority_queue.h" ], "header_base": "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include" } diff --git a/kv_store/frameworks/CMakeLists.txt b/kv_store/frameworks/CMakeLists.txt index 66c1be0e7d193d7328e8e98484921e676e7edd8e..bbade4ce0f702d70b11a6c1b9f1ed92fb6b49365 100644 --- a/kv_store/frameworks/CMakeLists.txt +++ b/kv_store/frameworks/CMakeLists.txt @@ -29,9 +29,9 @@ target_link_libraries(kvdb ${links}) target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/innerkits/distributeddata/include) target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces/innerkits/distributeddatamgr/include) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) -target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/include) -target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatasvc/include) -target_include_directories(kvdb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/kvdb/include) +target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/include) +target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatasvc/include) +target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/kvdb/include) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/src) target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_share/interfaces/inner_api/common/include/basic) @@ -40,12 +40,14 @@ target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_s target_include_directories(kvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_share/interfaces/inner_api/provider/include) target_link_libraries(jskvdb ${links} kvdb) +target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/include) target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/jskitsimpl/distributedkvstore/include) target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_share/interfaces/inner_api/provider/include) target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_share/interfaces/inner_api/common/include) target_link_libraries(jsolddb ${links} kvdb) +target_include_directories(jskvdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/innerkitsimpl/distributeddatafwk/include) target_include_directories(jsolddb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/jskitsimpl/distributeddata/include) target_include_directories(jsolddb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common) target_include_directories(jsolddb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../data_share/interfaces/inner_api/provider/include) diff --git a/kv_store/frameworks/common/test/BUILD.gn b/kv_store/frameworks/common/test/BUILD.gn index 08c9e2bae91228fd2963d7a774a1a01f8e180993..d75f7b802e240c025f455c969c17097a300ab14d 100644 --- a/kv_store/frameworks/common/test/BUILD.gn +++ b/kv_store/frameworks/common/test/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/test.gni") +import("//foundation/distributeddatamgr/kv_store/kv_store.gni") module_output_path = "kv_store/common" @@ -18,7 +19,10 @@ module_output_path = "kv_store/common" config("module_private_config") { visibility = [ ":*" ] - include_dirs = [ "../" ] + include_dirs = [ + "../", + "${kv_store_base_path}/interfaces/innerkits/distributeddata/include", + ] } ############################################################################### diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp index 6a2607e01eb7ce4fc37eb42f9ab70271afa653e6..73a7aefc2d316f1b7bf9f391333312d445897895 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp @@ -22,6 +22,7 @@ #include "log_print.h" #include "refbase.h" #include "store_manager.h" +#include "task_executor.h" namespace OHOS { namespace DistributedKv { @@ -164,5 +165,10 @@ void DistributedKvDataManager::UnRegisterKvStoreServiceDeathRecipient( } KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(kvStoreDeathRecipient); } + +void DistributedKvDataManager::SetExecutors(std::shared_ptr executors) +{ + TaskExecutor::GetInstance().SetExecutors(std::move(executors)); +} } // namespace DistributedKv } // namespace OHOS diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h index d3e62b64e7fb127ed2e8ea91d74f75a24b07ad1c..07ae4a75cb83db3bbfa3a05dd7059e2c85eaf3f3 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/task_executor.h @@ -31,13 +31,16 @@ public: uint64_t times = UNLIMITED_TIMES); bool Remove(TaskId taskId, bool wait = false); TaskId Reset(TaskId taskId, Duration interval); + void SetExecutors(std::shared_ptr executors); private: + std::mutex mtx_; size_t MAX_THREADS = 6; size_t MIN_THREADS = 0; - TaskExecutor(); + TaskExecutor() = default; ~TaskExecutor(); - std::shared_ptr pool_; + void GenerateExecutors(); + std::shared_ptr pool_ = nullptr; }; } // namespace OHOS #endif // DISTRIBUTED_DATA_TASK_EXECUTOR_H diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp index d39b0c1cd6e70a11a91d745269f01bb2bc44b5f9..af13f8c92f568ca9bc76f3409d5d20d400c01466 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/task_executor.cpp @@ -16,11 +16,6 @@ #include "task_executor.h" namespace OHOS { -TaskExecutor::TaskExecutor() -{ - pool_ = std::make_shared(MAX_THREADS, MIN_THREADS); -} - TaskExecutor::~TaskExecutor() { pool_ = nullptr; @@ -34,6 +29,9 @@ TaskExecutor &TaskExecutor::GetInstance() TaskExecutor::TaskId TaskExecutor::Execute(const Task &task) { + if (pool_ == nullptr) { + GenerateExecutors(); + } if (pool_ == nullptr) { return INVALID_TASK_ID; } @@ -42,6 +40,9 @@ TaskExecutor::TaskId TaskExecutor::Execute(const Task &task) TaskExecutor::TaskId TaskExecutor::Schedule(Duration delay, const Task &task, Duration interval, uint64_t times) { + if (pool_ == nullptr) { + GenerateExecutors(); + } if (pool_ == nullptr) { return INVALID_TASK_ID; } @@ -63,4 +64,20 @@ TaskExecutor::TaskId TaskExecutor::Reset(TaskExecutor::TaskId taskId, Duration i } return pool_->Reset(taskId, interval); } + +void TaskExecutor::SetExecutors(std::shared_ptr executors) +{ + std::lock_guard lock(mtx_); + if (pool_ == nullptr) { + pool_ = std::move(executors); + } +} + +void TaskExecutor::GenerateExecutors() +{ + std::lock_guard lock(mtx_); + if (pool_ == nullptr) { + pool_ = std::make_shared(MAX_THREADS, MIN_THREADS); + } +} } // namespace OHOS diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp index e6b173ecc9206023cec8b8636f06d1e1e904b2bb..7afeffc9142dd8ea0122ecf4010ea675486d4b57 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp @@ -22,7 +22,6 @@ #include "datashare_predicates.h" #include "single_kvstore.h" #include "kv_utils.h" -#include "kvstore_datashare_bridge.h" using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp index 57202fc14b73dd101b37362895d06e86de7ba5f9..b81d9b68052d5b0f81bb986a54e8673af715f4cf 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp @@ -17,8 +17,6 @@ #include "js_util.h" #include "log_print.h" #include "napi_queue.h" -#include "uv_queue.h" -#include "kvstore_datashare_bridge.h" #include "kv_utils.h" using namespace OHOS::DistributedKv; diff --git a/kv_store/frameworks/libs/distributeddb/BUILD.gn b/kv_store/frameworks/libs/distributeddb/BUILD.gn index 537f4f5ff8d8ff758ee11d1a0b38b9f28ba0ec14..0d3b550c50b32c92377f137c830cc3d7ce08bc4e 100644 --- a/kv_store/frameworks/libs/distributeddb/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/BUILD.gn @@ -68,6 +68,7 @@ config("distrdb_public_config") { "interfaces/include", "interfaces/include/relational", "include", + "gaussdb_rd/include", ] } @@ -87,9 +88,9 @@ ohos_shared_library("distributeddb") { ] configs += [ "//third_party/jsoncpp:jsoncpp_config" ] - ldflags = [ "-Wl,--exclude-libs,ALL" ] cflags_cc = [ "-fvisibility=hidden" ] deps += [ + "gaussdb_rd:gaussdb_rd", "//third_party/jsoncpp:jsoncpp", "//third_party/openssl:libcrypto_shared", ] diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h index af35f7a4a82d86881f45867e043560fa043aad47..a484460edb3a1bb1aa348699fb75c4621d28d120 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h @@ -28,6 +28,8 @@ public: static constexpr const char *MODIFY_FIELD = "#_modifyTime"; static constexpr const char *DELETE_FIELD = "#_deleted"; static constexpr const char *CURSOR_FIELD = "#_cursor"; + static constexpr const char *TYPE_FIELD = "#_type"; + static constexpr const char *QUERY_FIELD = "#_query"; static constexpr const char *ROW_ID_FIELD_NAME = "rowid"; static constexpr uint32_t MAX_UPLOAD_SIZE = 1024 * 512 * 3; // 1.5M // cloud data timestamp is utc ms precision diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h index c4604f802778d50d60905160cc835a48dae072cd..7af68da602b4692c60fd01bd197bfacdef81c4f1 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h @@ -34,6 +34,7 @@ struct CloudSyncData { CloudSyncBatch updData; CloudSyncBatch delData; bool isCloudForcePushStrategy = false; + int ignoredCount = 0; CloudSyncData() = default; CloudSyncData(const std::string &_tableName) : tableName(_tableName) {}; }; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h index f471c0fa996589ce720d6a3cb30e429906a4fe57..52120c555f9f4c13b89bb2aca4443b8927537535 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h @@ -89,7 +89,9 @@ public: static bool CaseInsensitiveCompare(std::string first, std::string second); - static bool CheckIsAlnumAndUnderscore(const std::string &text); + static bool CheckIsAlnumOrUnderscore(const std::string &text); + + static bool CheckQueryWithoutMultiTable(const Query &query); }; // Define short macro substitute for original long expression for convenience of using diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h index 40d72c5f41f54513a65d8c56bc30e7e0b294cb88..005394b9900a7472eadd2491990090f66b2b3203 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h @@ -31,6 +31,7 @@ public: static constexpr size_t MAX_INKEYS_SIZE = 128; static constexpr size_t MAX_SQL_ARGS_COUNT = 100; + static constexpr size_t MAX_IN_COUNT = 100; static constexpr int DB_TYPE_LOCAL = 1; static constexpr int DB_TYPE_MULTI_VER = 2; @@ -125,6 +126,8 @@ public: static constexpr uint32_t MIN_TIMEOUT = 5000; // 5s static constexpr uint32_t MAX_TIMEOUT = 60000; // 60s + static constexpr uint32_t MAX_SYNC_TIMEOUT = 300000; // 300s + static constexpr int INFINITE_WAIT = -1; // -1 is infinite waiting static constexpr uint8_t DEFAULT_COMPTRESS_RATE = 100; @@ -142,6 +145,9 @@ public: static constexpr int RELATIONAL_LOG_TABLE_FIELD_NUM = 7; // field num is relational distributed log table static constexpr uint64_t IGNORE_CONNECTION_ID = 0; + // Soft limit of a connection observer count. + static constexpr int MAX_OBSERVER_COUNT = 8; + // For relational static const std::string RELATIONAL_PREFIX; static const std::string TIMESTAMP_ALIAS; @@ -164,6 +170,10 @@ public: static constexpr uint32_t REMOTE_QUERY_MAX_SQL_LEN = 1000000U; static constexpr int HASH_KEY_SIZE = 32; // size of SHA256_DIGEST_LENGTH + + static constexpr const char *TABLE_IS_DROPPED = "table_is_dropped_"; + + static constexpr const char *SQLITE_INNER_ROWID = "_rowid_"; }; } // namespace DistributedDB #endif // DISTRIBUTEDDB_CONSTANT_H diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h index 2ff010a3b8d5bfa0bfdc1e811ab15eabf4035980..932f902c94ed7036ca24809e6d6675f789643c20 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h @@ -136,6 +136,7 @@ constexpr int E_CLOUD_FULL_RECORDS = (E_BASE + 115); // cloud's record is full constexpr int E_CLOUD_LOCK_ERROR = (E_BASE + 116); // cloud failed to get sync lock constexpr int E_CLOUD_ASSET_SPACE_INSUFFICIENT = (E_BASE + 117); // cloud failed to download asset constexpr int E_CLOUD_INVALID_ASSET = (E_BASE + 118); // the asset is invalid +constexpr int E_TASK_PAUSED = (E_BASE + 119); // the task was paused, don't finished it // Num 150+ is reserved for schema related errno, since it may be added regularly constexpr int E_JSON_PARSE_FAIL = (E_BASE + 150); // Parse json fail in grammatical level constexpr int E_JSON_INSERT_PATH_EXIST = (E_BASE + 151); // Path already exist before insert diff --git a/kv_store/frameworks/libs/distributeddb/common/include/platform_specific.h b/kv_store/frameworks/libs/distributeddb/common/include/platform_specific.h index cee53c54a233383266908a4244b58e83d3b1d9df..399a18a73f63916485e1c5acd9ac7ea60199b753 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/platform_specific.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/platform_specific.h @@ -69,11 +69,11 @@ int SetFilePermissions(const std::string &fileName, uint32_t permissions); int RenameFilePath(const std::string &oldFilePath, const std::string &newFilePath); -int OpenFile(const std::string &fileName, FileHandle *&handle); -int CloseFile(FileHandle *handle); +int OpenFile(const std::string &fileName, FileHandle *&fileHandle); +int CloseFile(FileHandle *fileHandle); -int FileLock(const FileHandle *handle, bool isBlock); // be careful use block=true, may block process -int FileUnlock(FileHandle *handle); +int FileLock(const FileHandle *fileHandle, bool isBlock); // be careful use block=true, may block process +int FileUnlock(FileHandle *fileHandle); } // namespace OS } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/include/relational/relational_schema_object.h b/kv_store/frameworks/libs/distributeddb/common/include/relational/relational_schema_object.h index 2f6e3965cdc3edebc7fa9e321c80a6c54e9c1f19..001e65eca412be26c9f4460689a52831467d13f8 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/relational/relational_schema_object.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/relational/relational_schema_object.h @@ -39,7 +39,7 @@ public: // Should be called on an invalid SchemaObject, create new SchemaObject if need to reparse int ParseFromSchemaString(const std::string &inSchemaString) override; - void AddRelationalTable(const TableInfo& table); + void AddRelationalTable(const TableInfo &table); void RemoveRelationalTable(const std::string &tableName); diff --git a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h index c7fa00cc924e62ab481b022fe8ef29fd7e619173..c972a42c8fb3b52b595633ed49cb55c7703c38d5 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h @@ -161,7 +161,7 @@ public: virtual int AssetToBlob(const Asset &asset, std::vector &blob) = 0; virtual int AssetsToBlob(const Assets &assets, std::vector &blob) = 0; virtual int BlobToAsset(const std::vector &blob, Asset &asset) = 0; - virtual int BlobToAssets(std::vector &blob, Assets &assets) = 0; + virtual int BlobToAssets(const std::vector &blob, Assets &assets) = 0; protected: RuntimeContext() = default; virtual ~RuntimeContext() {} diff --git a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp index 2af29a0d2679ba0ab76e90fa98d4e02d7c4a0777..11e61d77f22b67a639759d9f0e48a21f86dac84e 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp @@ -1251,8 +1251,8 @@ int AutoLaunch::RegisterRelationalObserver(AutoLaunchItem &autoLaunchItem, const return E_OK; } RelationalStoreConnection *conn = static_cast(autoLaunchItem.conn); - conn->RegisterObserverAction([this, autoLaunchItem, identifier](const std::string &changedDevice, - ChangedData &&changedData, bool isChangedData) { + (void)conn->RegisterObserverAction(autoLaunchItem.storeObserver, [this, autoLaunchItem, identifier]( + const std::string &changedDevice, ChangedData &&changedData, bool isChangedData) { if (isChangedData && autoLaunchItem.storeObserver) { LOGD("begin to observer on changed data"); autoLaunchItem.storeObserver->OnChange( diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp index 40c1abaecb5d6c4843f5605e616a8ace2e0a0ae9..801428dce444741e7eb9e2bb9557f4aa6e0e9aba 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -20,6 +20,7 @@ #include "db_errno.h" #include "platform_specific.h" +#include "query_sync_object.h" #include "hash.h" #include "runtime_context.h" #include "value_hash_calc.h" @@ -447,11 +448,25 @@ bool DBCommon::CaseInsensitiveCompare(std::string first, std::string second) return first == second; } -bool DBCommon::CheckIsAlnumAndUnderscore(const std::string &text) +bool DBCommon::CheckIsAlnumOrUnderscore(const std::string &text) { auto iter = std::find_if_not(text.begin(), text.end(), [](char c) { return (std::isalnum(c) || c == '_'); }); return iter == text.end(); } + +bool DBCommon::CheckQueryWithoutMultiTable(const Query &query) +{ + QuerySyncObject syncObject(query); + if (!syncObject.GetRelationTableNames().empty()) { + LOGE("check query from tables failed!"); + return false; + } + if (!QuerySyncObject::GetQuerySyncObject(query).empty()) { + LOGE("check query from table failed!"); + return false; + } + return true; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp index 9ce5e35163d153d90bd7ac18188774f2bfd1283e..6bc209c20e0c6e3e525817fa9ea08fa4b3f8f342 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp @@ -72,7 +72,6 @@ const std::string DBConstant::LOG_POSTFIX = "_log"; const std::string DBConstant::LOG_TABLE_VERSION_1 = "1.0"; const std::string DBConstant::LOG_TABLE_VERSION_2 = "2.0"; -const char *LOG_TABLE_VERSION_3 = "3.0"; const std::string DBConstant::LOG_TABLE_VERSION_CURRENT = "4.0"; const std::string DBConstant::LOG_TABLE_VERSION_KEY = "log_table_version"; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp index b2847e694cd4df6dea3ae2b96a93fae2dd7e775d..568646c384a8c04b4374e230ced3bb1dd4ad3484 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp @@ -197,7 +197,7 @@ uint8_t ParamCheckUtils::GetValidCompressionRate(uint8_t compressionRate) bool ParamCheckUtils::CheckRelationalTableName(const std::string &tableName) { - if (!DBCommon::CheckIsAlnumAndUnderscore(tableName)) { + if (!DBCommon::CheckIsAlnumOrUnderscore(tableName)) { return false; } return tableName.compare(0, DBConstant::SYSTEM_TABLE_PREFIX.size(), DBConstant::SYSTEM_TABLE_PREFIX) != 0; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp b/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp index 721b9f8872aee524dec826f766f50fc463bb2a03..adc7367a50e5c696cad473a110414e53536e34fa 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp @@ -306,43 +306,43 @@ int SetFilePermissions(const std::string &fileName, uint32_t permissions) return E_OK; } -int OpenFile(const std::string &fileName, FileHandle *&handle) +int OpenFile(const std::string &fileName, FileHandle *&fileHandle) { - handle = new (std::nothrow)FileHandle; - if (handle == nullptr) { + fileHandle = new (std::nothrow)FileHandle; + if (fileHandle == nullptr) { return -E_OUT_OF_MEMORY; } - handle->handle = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE); - if (handle->handle < 0) { + fileHandle->handle = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE); + if (fileHandle->handle < 0) { LOGE("[FileLock] can not open file when lock it:[%d]", errno); - delete handle; - handle = nullptr; + delete fileHandle; + fileHandle = nullptr; return -E_SYSTEM_API_FAIL; } return E_OK; } -int CloseFile(FileHandle *handle) +int CloseFile(FileHandle *fileHandle) { - if (handle == nullptr || handle->handle == -1) { + if (fileHandle == nullptr || fileHandle->handle == -1) { LOGI("[CloseFile] file handle is invalid!"); return -E_INVALID_ARGS; } - if (close(handle->handle) != 0) { + if (close(fileHandle->handle) != 0) { LOGE("close file failed, errno:%d", errno); return -E_SYSTEM_API_FAIL; } - delete handle; + delete fileHandle; return E_OK; } -int FileLock(const FileHandle *handle, bool isBlock) +int FileLock(const FileHandle *fileHandle, bool isBlock) { - if (handle == nullptr) { + if (fileHandle == nullptr) { return -E_INVALID_ARGS; } - if (handle->handle < 0) { + if (fileHandle->handle < 0) { LOGE("[FileLock] can not open file when lock it:[%d]", errno); return -E_SYSTEM_API_FAIL; } @@ -350,7 +350,7 @@ int FileLock(const FileHandle *handle, bool isBlock) return E_OK; } -int FileUnlock(FileHandle *handle) +int FileUnlock(FileHandle *fileHandle) { return E_OK; } @@ -598,42 +598,43 @@ int SetFilePermissions(const std::string &fileName, uint32_t permissions) return E_OK; } -int OpenFile(const std::string &fileName, FileHandle *&handle) +int OpenFile(const std::string &fileName, FileHandle *&fileHandle) { - handle = new (std::nothrow)FileHandle; - if (handle == nullptr) { + fileHandle = new (std::nothrow)FileHandle; + if (fileHandle == nullptr) { return -E_OUT_OF_MEMORY; } - handle->handle = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP)); - if (handle->handle < 0) { + fileHandle->handle = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP)); + if (fileHandle->handle < 0) { LOGE("[FileLock] can not open file when lock it:[%d]", errno); - delete handle; - handle = nullptr; + delete fileHandle; + fileHandle = nullptr; return -E_SYSTEM_API_FAIL; } return E_OK; } -int CloseFile(FileHandle *handle) +int CloseFile(FileHandle *fileHandle) { - if (handle == nullptr || handle->handle == -1) { + if (fileHandle == nullptr || fileHandle->handle == -1) { LOGI("[CloseFile] file handle is invalid!"); return -E_INVALID_ARGS; } - if (close(handle->handle) != 0) { + if (close(fileHandle->handle) != 0) { LOGE("close file failed, errno:%d", errno); return -E_SYSTEM_API_FAIL; } - delete handle; + delete fileHandle; + fileHandle = nullptr; return E_OK; } -int FileLock(const FileHandle *handle, bool isBlock) +int FileLock(const FileHandle *fileHandle, bool isBlock) { - if (handle == nullptr) { + if (fileHandle == nullptr) { return -E_INVALID_ARGS; } - if (handle->handle < 0) { + if (fileHandle->handle < 0) { LOGE("[FileLock] can not open file when lock it:[%d]", errno); return -E_SYSTEM_API_FAIL; } @@ -645,7 +646,7 @@ int FileLock(const FileHandle *handle, bool isBlock) fileLockInfo.l_start = 0; fileLockInfo.l_len = 0; LOGD("Lock file isBlock[%d]", isBlock); - if (fcntl(handle->handle, isBlock ? F_SETLKW : F_SETLK, &fileLockInfo) == -1 && !isBlock) { + if (fcntl(fileHandle->handle, isBlock ? F_SETLKW : F_SETLK, &fileLockInfo) == -1 && !isBlock) { LOGD("Lock file is Blocked, please retry!"); return -E_BUSY; } @@ -653,9 +654,9 @@ int FileLock(const FileHandle *handle, bool isBlock) return E_OK; } -int FileUnlock(FileHandle *handle) +int FileUnlock(FileHandle *fileHandle) { - if (handle == nullptr || handle->handle == -1) { + if (fileHandle == nullptr || fileHandle->handle == -1) { LOGI("[FileUnlock] file handle is invalid!"); return E_OK; } @@ -666,7 +667,7 @@ int FileUnlock(FileHandle *handle) fileLockInfo.l_whence = SEEK_SET; fileLockInfo.l_start = 0; fileLockInfo.l_len = 0; - if (fcntl(handle->handle, F_SETLK, &fileLockInfo) == -1) { + if (fcntl(fileHandle->handle, F_SETLK, &fileLockInfo) == -1) { LOGE("Unlock file failed. errno:%d", errno); return -E_SYSTEM_API_FAIL; } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/query.cpp b/kv_store/frameworks/libs/distributeddb/common/src/query.cpp index a76dcf3cb89c35c851a32f076ce3dadfc5257de6..17910386fa58dbbcd5cf2fb6fc58e502c7742414 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/query.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/query.cpp @@ -37,101 +37,93 @@ Query &Query::FromTable(const std::vector &tableNames) return *this; } +Query &Query::From(const std::string &tableName) +{ + queryExpression_.From(tableName); + return *this; +} + Query &Query::BeginGroup() { queryExpression_.BeginGroup(); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::EndGroup() { queryExpression_.EndGroup(); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::IsNotNull(const std::string &field) { queryExpression_.IsNotNull(field); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::PrefixKey(const std::vector &key) { queryExpression_.QueryByPrefixKey(key); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::SuggestIndex(const std::string &indexName) { queryExpression_.QueryBySuggestIndex(indexName); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::InKeys(const std::set &keys) { queryExpression_.InKeys(keys); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::OrderBy(const std::string &field, bool isAsc) { queryExpression_.OrderBy(field, isAsc); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::OrderByWriteTime(bool isAsc) { queryExpression_.SetSortType(isAsc); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::Limit(int number, int offset) { queryExpression_.Limit(number, offset); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::Like(const std::string &field, const std::string &value) { queryExpression_.Like(field, value); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::NotLike(const std::string &field, const std::string &value) { queryExpression_.NotLike(field, value); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::IsNull(const std::string &field) { queryExpression_.IsNull(field); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::And() { queryExpression_.And(); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } Query &Query::Or() { queryExpression_.Or(); - queryExpression_.SetIsDeviceSyncQuery(true); return *this; } @@ -176,9 +168,4 @@ void Query::ExecuteCompareOperation(QueryObjType operType, const std::string &fi return; } } - -void Query::SetIsDeviceSyncQuery(bool isDeviceSync) -{ - queryExpression_.SetIsDeviceSyncQuery(isDeviceSync); -} } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp b/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp index ff8b0832ae0ea126fc0d03e4ffc2afbebc740340..51b1c07e1615c7dbe13857b78dd524069768a489 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp @@ -25,6 +25,14 @@ namespace { void QueryExpression::AssemblyQueryInfo(const QueryObjType queryOperType, const std::string& field, const QueryValueType type, const std::vector &values, bool isNeedFieldPath = true) { + if (useFromTable_) { + expressions_[fromTable_].AssemblyQueryInfo(queryOperType, field, type, values, isNeedFieldPath); + SetNotSupportIfNeed(queryOperType); + return; + } + if (!tables_.empty()) { + validStatus_ = -E_NOT_SUPPORT; + } if (queryInfo_.size() > MAX_OPR_TIMES) { SetErrFlag(false); LOGE("Operate too much times!"); @@ -55,6 +63,9 @@ void QueryExpression::AssemblyQueryInfo(const QueryObjType queryOperType, const } else { formatedField = field; } + if (!queryInfo_.empty() && queryInfo_.back().operFlag == queryOperType) { + validStatus_ = -E_INVALID_ARGS; + } queryInfo_.emplace_back(QueryObjNode{queryOperType, formatedField, type, values}); } @@ -184,6 +195,12 @@ void QueryExpression::Or() void QueryExpression::QueryByPrefixKey(const std::vector &key) { + if (useFromTable_) { + expressions_[fromTable_].QueryByPrefixKey(key); + validStatus_ = -E_NOT_SUPPORT; + return; + } + SetNotSupportIfFromTables(); queryInfo_.emplace_front(QueryObjNode{QueryObjType::QUERY_BY_KEY_PREFIX, std::string(), QueryValueType::VALUE_TYPE_NULL, std::vector()}); prefixKey_ = key; @@ -191,6 +208,12 @@ void QueryExpression::QueryByPrefixKey(const std::vector &key) void QueryExpression::QueryBySuggestIndex(const std::string &indexName) { + if (useFromTable_) { + expressions_[fromTable_].QueryBySuggestIndex(indexName); + validStatus_ = -E_NOT_SUPPORT; + return; + } + SetNotSupportIfFromTables(); queryInfo_.emplace_back(QueryObjNode{QueryObjType::SUGGEST_INDEX, indexName, QueryValueType::VALUE_TYPE_STRING, std::vector()}); suggestIndex_ = indexName; @@ -198,6 +221,12 @@ void QueryExpression::QueryBySuggestIndex(const std::string &indexName) void QueryExpression::InKeys(const std::set &keys) { + if (useFromTable_) { + expressions_[fromTable_].InKeys(keys); + validStatus_ = -E_NOT_SUPPORT; + return; + } + SetNotSupportIfFromTables(); queryInfo_.emplace_front(QueryObjNode{QueryObjType::IN_KEYS, std::string(), QueryValueType::VALUE_TYPE_NULL, std::vector()}); keys_ = keys; @@ -246,12 +275,22 @@ const std::set &QueryExpression::GetKeys() const void QueryExpression::BeginGroup() { + if (useFromTable_) { + expressions_[fromTable_].BeginGroup(); + return; + } + SetNotSupportIfFromTables(); queryInfo_.emplace_back(QueryObjNode{QueryObjType::BEGIN_GROUP, std::string(), QueryValueType::VALUE_TYPE_NULL, std::vector()}); } void QueryExpression::EndGroup() { + if (useFromTable_) { + expressions_[fromTable_].EndGroup(); + return; + } + SetNotSupportIfFromTables(); queryInfo_.emplace_back(QueryObjNode{QueryObjType::END_GROUP, std::string(), QueryValueType::VALUE_TYPE_NULL, std::vector()}); } @@ -283,6 +322,12 @@ int QueryExpression::GetSortType() const void QueryExpression::SetSortType(bool isAsc) { + if (useFromTable_) { + expressions_[fromTable_].SetSortType(isAsc); + validStatus_ = -E_NOT_SUPPORT; + return; + } + SetNotSupportIfFromTables(); WriteTimeSort sortType = isAsc ? WriteTimeSort::TIMESTAMP_ASC : WriteTimeSort::TIMESTAMP_DESC; sortType_ = static_cast(sortType); } @@ -294,16 +339,98 @@ std::vector QueryExpression::GetTables() void QueryExpression::SetTables(const std::vector &tableNames) { - tables_ = tableNames; + // filter same table + std::vector syncTable; + std::set addTable; + for (const auto &table: tableNames) { + if (addTable.find(table) == addTable.end()) { + addTable.insert(table); + syncTable.push_back(table); + } + } + tables_ = syncTable; + if (useFromTable_) { + validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT; + } + SetNotSupportIfCondition(); +} + +void QueryExpression::From(const std::string &tableName) +{ + useFromTable_ = true; + fromTable_ = tableName; + for (const auto &item: tableSequence_) { + if (item == tableName) { + return; + } + } + tableSequence_.push_back(fromTable_); + expressions_[fromTable_].SetTableName(fromTable_); + if (tableName.empty()) { + validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_INVALID_ARGS; + } else if (!tables_.empty()) { + validStatus_ = validStatus_ != E_OK ? validStatus_ : -E_NOT_SUPPORT; + } + SetNotSupportIfFromTables(); + SetNotSupportIfCondition(); +} + +int QueryExpression::GetExpressionStatus() const +{ + return validStatus_; } -void QueryExpression::SetIsDeviceSyncQuery(bool isDeviceSync) +std::vector QueryExpression::GetQueryExpressions() const { - isWithDeviceSyncQuery_ = isDeviceSync; + if (!useFromTable_) { + return {}; + } + std::vector res; + for (const auto &item : tableSequence_) { + res.push_back(expressions_.at(item)); + } + return res; } -bool QueryExpression::GetIsDeviceSyncQuery() const +void QueryExpression::SetNotSupportIfFromTables() { - return isWithDeviceSyncQuery_; + if (validStatus_ != E_OK) { + return; + } + if (!tables_.empty()) { + validStatus_ = -E_NOT_SUPPORT; + } +} + +void QueryExpression::SetNotSupportIfCondition() +{ + if (validStatus_ != E_OK) { + return; + } + if (!queryInfo_.empty()) { + validStatus_ = -E_NOT_SUPPORT; + } +} + +void QueryExpression::SetNotSupportIfNeed(QueryObjType type) +{ + if (validStatus_ != E_OK) { + return; + } + if (type != QueryObjType::IN && type != QueryObjType::EQUALTO && type != QueryObjType::AND && + type != QueryObjType::OR) { + validStatus_ = -E_NOT_SUPPORT; + } + if (validStatus_ != E_OK) { + return; + } + for (const auto &item: queryInfo_) { + if (((item.operFlag == QueryObjType::EQUALTO) && (type == QueryObjType::IN)) || + ((item.operFlag == QueryObjType::IN) && (type == QueryObjType::EQUALTO))) { + validStatus_ = -E_NOT_SUPPORT; + LOGW("[Query] Not support use in and equal to at same time when use from table"); + break; + } + } } } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp b/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp index 075be5bf7a0898d74b586505f6719b6e6a0c38d0..68ef8a8dc941fe7375ee6a985a684da0ebc0c601 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_schema_object.cpp @@ -358,7 +358,7 @@ int RelationalSchemaObject::ParseCheckTableName(const JsonObject &inJsonObject, int errCode = GetMemberFromJsonObject(inJsonObject, "NAME", FieldType::LEAF_FIELD_STRING, true, fieldValue); if (errCode == E_OK) { - if (!DBCommon::CheckIsAlnumAndUnderscore(fieldValue.stringValue)) { + if (!DBCommon::CheckIsAlnumOrUnderscore(fieldValue.stringValue)) { LOGE("[RelationalSchema][Parse] Invalid characters in table name, err=%d.", errCode); return -E_SCHEMA_PARSE_FAIL; } @@ -390,7 +390,7 @@ int RelationalSchemaObject::ParseCheckTableDefine(const JsonObject &inJsonObject return errCode; } - if (!DBCommon::CheckIsAlnumAndUnderscore(field.first[1])) { + if (!DBCommon::CheckIsAlnumOrUnderscore(field.first[1])) { LOGE("[RelationalSchema][Parse] Invalid characters in field name, err=%d.", errCode); return -E_SCHEMA_PARSE_FAIL; } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp index 6c9acf424d56a4e8423f280f4f7d77288f62a81a..9814ca1c0b7ee427dc31398284d15a3822bf1d73 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -969,7 +969,7 @@ int RuntimeContextImpl::BlobToAsset(const std::vector &blob, Asset &ass return E_OK; } -int RuntimeContextImpl::BlobToAssets(std::vector &blob, Assets &assets) +int RuntimeContextImpl::BlobToAssets(const std::vector &blob, Assets &assets) { std::shared_lock autoLock(dataTranslateLock_); if (dataTranslate_ == nullptr) { diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h index 5dfc7187f33f290f9b5078c04024294e67f1d492..733314119eabe912a821bde08213d62167e6cc7b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h @@ -146,7 +146,7 @@ public: int AssetToBlob(const Asset &asset, std::vector &blob) override; int AssetsToBlob(const Assets &assets, std::vector &blob) override; int BlobToAsset(const std::vector &blob, Asset &asset) override; - int BlobToAssets(std::vector &blob, Assets &assets) override; + int BlobToAssets(const std::vector &blob, Assets &assets) 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. diff --git a/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.cpp index 01a7b8fe6a7e7362b66bcaaa970517bf0af0fd00..13ed16c2d0839c21899253fc379130256548f740 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.cpp @@ -138,7 +138,7 @@ bool TaskPoolImpl::IdleExit(std::unique_lock &lock) if (!isGenericWorker && (curThreads_ > minThreads_)) { std::cv_status status = hasTasks_.wait_for(lock, std::chrono::seconds(IDLE_WAIT_PERIOD)); - if (status == std::cv_status::timeout && IsNoTaskExecute()) { + if (status == std::cv_status::timeout && IsExecutingTasksEmpty()) { --idleThreads_; return true; } @@ -292,7 +292,7 @@ void TaskPoolImpl::TryToSpawnThreads() (void)(SpawnThreads(false)); } -bool TaskPoolImpl::IsNoTaskExecute() const +bool TaskPoolImpl::IsExecutingTasksEmpty() const { if (genericTaskCount_ > 0) { return false; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.h b/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.h index 4342be15d05d907c908b13e850cf01c28f4db9b4..a530f3fa295a188103b947ffee92f5e4560c36cf 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.h +++ b/kv_store/frameworks/libs/distributeddb/common/src/task_pool_impl.h @@ -61,7 +61,7 @@ private: void TaskWorker(); void FinishExecuteTask(TaskQueue *taskQueue); void TryToSpawnThreads(); - bool IsNoTaskExecute() const; + bool IsExecutingTasksEmpty() const; // Member Variables. static constexpr int IDLE_WAIT_PERIOD = 1; // wait 1 second before exiting. diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp index 0b1efd0abfab23d61a0c6d87c02c4394899b16f2..741ba34c700bcb95a11db853a1ee5f969d321680 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -371,7 +371,7 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, u for (uint32_t index = startIndex; index < static_cast(eachPacket.size()); ++index) { auto &entry = eachPacket[index]; LOGI("[CommAggr][SendPackets] DoSendBytes, dstTarget=%s{private}, extendHeadLength=%" PRIu32 - ", totalLength=%" PRIu32 ".", inTask.dstTarget.c_str(), entry.second.first, entry.second.second); + ", packetLength=%" PRIu32 ".", inTask.dstTarget.c_str(), entry.second.first, entry.second.second); ProtocolProto::DisplayPacketInformation(entry.first + entry.second.first, entry.second.second); errCode = adapterHandle_->SendBytes(inTask.dstTarget, entry.first, entry.second.second, totalLength); { @@ -389,7 +389,7 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, u } } if (errCode == -E_WAIT_RETRY) { - const int RETRY_INTERVAL = 1000; + constexpr int RETRY_INTERVAL = 1000; // 1000ms TimerId timerId = 0u; const std::string target = inTask.dstTarget; RefObject::IncObjRef(this); diff --git a/kv_store/frameworks/libs/distributeddb/distributeddb.gni b/kv_store/frameworks/libs/distributeddb/distributeddb.gni index 33a4b990313ec66522247ba053f016f76c98429f..3b0a403acbd6d6b1c856e347467999d9100e2a32 100644 --- a/kv_store/frameworks/libs/distributeddb/distributeddb.gni +++ b/kv_store/frameworks/libs/distributeddb/distributeddb.gni @@ -184,6 +184,7 @@ distributeddb_src = [ "${distributeddb_path}/syncer/src/cloud/cloud_force_push_strategy.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_merge_strategy.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_db_proxy.cpp", + "${distributeddb_path}/syncer/src/cloud/cloud_locker.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_syncer.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_sync_tag_assets.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_sync_utils.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn similarity index 85% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn index 3f44a3739d2354fb04b8ed9150bd0a499a73b6a5..acebb6810710f6b0d560a8e75b2472893331b199 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn @@ -45,18 +45,25 @@ group("build_module") { deps = [ ":gaussdb_rd" ] } -ohos_shared_library("gaussdb_rd") { +ohos_static_library("gaussdb_rd") { sources = [ "src/common/src/collection_option.cpp", "src/common/src/db_config.cpp", - "src/common/src/db_constant.cpp", + "src/common/src/grd_api_manager.cpp", "src/common/src/json_common.cpp", "src/common/src/log_print.cpp", "src/common/src/os_api.cpp", "src/executor/base/grd_db_api.cpp", + "src/executor/base/grd_db_api_inner.cpp", "src/executor/document/check_common.cpp", "src/executor/document/grd_document_api.cpp", + "src/executor/document/grd_document_api_inner.cpp", "src/executor/document/grd_resultset_api.cpp", + "src/executor/document/grd_resultset_api_inner.cpp", + "src/executor/kv/grd_kv_api.cpp", + "src/executor/kv/grd_kv_api_inner.cpp", + "src/executor/shared_obj/grd_sequence_api.cpp", + "src/executor/shared_obj/grd_sequence_api_inner.cpp", "src/interface/src/collection.cpp", "src/interface/src/doc_errno.cpp", "src/interface/src/document_key.cpp", @@ -89,5 +96,5 @@ ohos_shared_library("gaussdb_rd") { ] subsystem_name = "distributeddatamgr" - part_name = "datamgr_service" + part_name = "kv_store" } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/CMakeLists.txt b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/CMakeLists.txt similarity index 90% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/CMakeLists.txt rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/CMakeLists.txt index dc4311de05e39f3ef76eb9a3319d1bd3bbca8372..f935c0c5a410a0f885bd91274c0538f545711898 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/CMakeLists.txt +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/CMakeLists.txt @@ -4,7 +4,6 @@ project(document_ut) set(GAUSE_SOURCE_DIR "${PROJECT_SOURCE_DIR}") file(GLOB_RECURSE DOCUMENT_SRC ${GAUSE_SOURCE_DIR}/src/*.cpp) -message(STATUS "hanlu ${GAUSE_SOURCE_DIR} ${DOCUMENT_SRC}") include_directories( ${GAUSE_SOURCE_DIR}/include ${GAUSE_SOURCE_DIR}/src/storage @@ -30,9 +29,9 @@ include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../utils_native/base/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../utils_native/safwk/native/include) -message(STATUS "hanlu3 ${CMAKE_CURRENT_SOURCE_DIR}../../../../../../utils_native/base/include") add_library(document_ut SHARED ${DOCUMENT_SRC}) set(links mock kvdb adapter data_share secure) target_link_libraries(document_ut ${links}) +target_include_directories(document_ut PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_db_api.h similarity index 91% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_db_api.h index cc1da4b99893780debae8e44b0ce03ca6acfcb03..c8b29240694b4a3e502d19799498ec3a1f7ada07 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_db_api.h @@ -15,11 +15,9 @@ #ifndef GRD_DB_API_H #define GRD_DB_API_H - #include #include "grd_type_export.h" - #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -28,8 +26,9 @@ GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t f GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags); -GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags); +GRD_API int32_t GRD_IndexPreload(GRD_DB *db, const char *collectionName); +GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags); #ifdef __cplusplus } #endif // __cplusplus diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_error.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_error.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_error.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_error.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_resultset_api.h similarity index 86% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_resultset_api.h index c9365f189c2f21a3f9da8f217db78d44d68d1b2c..30ce4a453003a30d1020f3b20dbaedfefb87dbe5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_resultset_api.h @@ -23,17 +23,19 @@ #ifdef __cplusplus extern "C" { #endif // __cplusplus - typedef struct GRD_ResultSet GRD_ResultSet; GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet); +GRD_API int32_t GRD_Prev(GRD_ResultSet *resultSet); + GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value); +GRD_API int32_t GRD_Fetch(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value); + GRD_API int32_t GRD_FreeValue(char *value); GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet); - #ifdef __cplusplus } #endif // __cplusplus diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h similarity index 81% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h index d116ea2263c540ea73c159c185bb57c3c1191dec..bc940e5c5c2f185c7d2c486d56cc78816c38d6b8 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h @@ -15,7 +15,7 @@ #ifndef GRD_TYPE_EXPORT_H #define GRD_TYPE_EXPORT_H - +#include #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -54,6 +54,22 @@ typedef struct Query { const char *projection; } Query; +typedef struct GRD_KVItem { + void *data; + uint32_t dataLen; +} GRD_KVItemT; + +typedef enum KvScanMode { + KV_SCAN_PREFIX = 0, + KV_SCAN_EQUAL_OR_LESS_KEY = 1, + KV_SCAN_EQUAL_OR_GREATER_KEY = 2, + KV_SCAN_BUTT +} KvScanModeE; + +typedef struct GRD_ResultSet GRD_ResultSet; +typedef struct GRD_DB GRD_DB; +typedef struct GRD_KVBatch GRD_KVBatchT; + /** * @brief Flags for create and drop collection */ diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_document/grd_document_api.h similarity index 98% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_document/grd_document_api.h index bd6e77c2db64e861e84c7d5b771cd2fa9a676398..d01d54e56795f895c5cd6d7360042ab1de418774 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_document/grd_document_api.h @@ -41,7 +41,6 @@ GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char uint32_t flags); GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags); - #ifdef __cplusplus } #endif diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h new file mode 100644 index 0000000000000000000000000000000000000000..50f33bc341a22829fed58405e7ce196b7882efa6 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h @@ -0,0 +1,49 @@ +/* +* 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 GRD_KV_API_H +#define GRD_KV_API_H + +#include + +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" + +#ifdef __cplusplus +extern "C" { +#endif +GRD_API int32_t GRD_KVPut(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); + +GRD_API int32_t GRD_KVGet(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); + +GRD_API int32_t GRD_KVDel(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key); + +GRD_API int32_t GRD_KVScan(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, KvScanModeE mode, + GRD_ResultSet **resultSet); + +GRD_API int32_t GRD_KVFreeItem(GRD_KVItemT *item); + +GRD_API int32_t GRD_KVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch); + +GRD_API int32_t GRD_KVBatchPushback(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, + GRD_KVBatchT *batch); + +GRD_API int32_t GRD_KVBatchDel(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch); + +GRD_API int32_t GRD_KVBatchDestory(GRD_KVBatchT *batch); +#ifdef __cplusplus +} +#endif +#endif // GRD_DOCUMENT_API_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/same_process_ipc_guard.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_shared_obj/grd_sequence_api.h similarity index 55% rename from datamgr_service/services/distributeddataservice/service/udmf/same_process_ipc_guard.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_shared_obj/grd_sequence_api.h index 8db7d8243929b3824de1d2e422b8201dd18ee7b8..7eaf2b4c0f6b227e66d42853bdfad8960d06262f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/same_process_ipc_guard.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_shared_obj/grd_sequence_api.h @@ -13,31 +13,21 @@ * limitations under the License. */ -#ifndef UDMF_SAMEPROCESSIPCGUARD_H -#define UDMF_SAMEPROCESSIPCGUARD_H +#ifndef GRD_SEQUENCE_API_H +#define GRD_SEQUENCE_API_H -#include +#include -#include "ipc_skeleton.h" +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" -namespace OHOS { -namespace UDMF { -class SameProcessIpcGuard { -public: - SameProcessIpcGuard() - { - identity = IPCSkeleton::ResetCallingIdentity(); - } +#ifdef __cplusplus +extern "C" { +#endif +GRD_API int32_t GRD_CreateSeq(GRD_DB *db, const char *sequenceName, uint32_t flags); - ~SameProcessIpcGuard() - { - IPCSkeleton::SetCallingIdentity(identity); - } - -private: - std::string identity; -}; -} // namespace UDMF -} // namespace OHOS - -#endif // UDMF_SAMEPROCESSIPCGUARD_H \ No newline at end of file +GRD_API int32_t GRD_DropSeq(GRD_DB *db, const char *sequenceName, uint32_t flags); +#ifdef __cplusplus +} +#endif +#endif // GRD_DOCUMENT_API_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/collection_option.h similarity index 88% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/collection_option.h index 6062f9fec76d23cb0179f39dfc5eda368e381599..ddb4cf3cdfd36c067de436519e1ab3bb61edaf35 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/collection_option.h @@ -23,10 +23,11 @@ class CollectionOption final { public: static CollectionOption ReadOption(const std::string &optStr, int &errCode); +private: + CollectionOption() = default; + CollectionOption(const CollectionOption &collectionOption) = default; bool operator==(const CollectionOption &targetOption) const; bool operator!=(const CollectionOption &targetOption) const; - -private: std::string option_ = "{}"; uint32_t maxDoc_ = UINT32_MAX; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_config.h similarity index 94% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_config.h index faa1cca2e7d8a67d9591d65dae6c4bc5fbd2c636..1b9e1a5e4730b4fa988384e4c425d86446ae6716 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_config.h @@ -22,8 +22,6 @@ namespace DocumentDB { class DBConfig final { public: static DBConfig ReadConfig(const std::string &confStr, int &errCode); - - DBConfig() = default; ~DBConfig() = default; std::string ToString() const; @@ -37,7 +35,9 @@ public: private: static DBConfig GetDBConfigFromJsonStr(const std::string &confStr, int &errCode); - + DBConfig() = default; + DBConfig(const DBConfig&) = default; + DBConfig(DBConfig&&) = default; std::string configStr_ = {}; int32_t pageSize_ = 4; // 4: default page size k uint32_t redoFlushByTrx_ = 0; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_constant.h similarity index 89% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_constant.h index 7bafc8020912d9686a4c2108c41b481bc9f1623d..efd1d88e01d47ba6e48802095a35ae9b1b4ba8bc 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/db_constant.h @@ -21,7 +21,7 @@ namespace DocumentDB { class DBConstant final { public: - static const std::string COLL_PREFIX; // = "GRD_COLL_"; + static constexpr const char *COLL_PREFIX = "GRD_COLL_"; }; } // namespace DocumentDB #endif // DB_CONSTANT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/doc_limit.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/doc_limit.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/document_type.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/document_type.h diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..45a1541e949a6410b63241baab96ecc8679f22b4 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h @@ -0,0 +1,88 @@ +/* +* 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 GRD_API_MANAGER_H +#define GRD_API_MANAGER_H + +#include "grd_base/grd_type_export.h" + +namespace DocumentDB { +typedef int32_t (*DBOpen)(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db); +typedef int32_t (*DBClose)(GRD_DB *db, uint32_t flags); +typedef int32_t (*DBFlush)(GRD_DB *db, uint32_t flags); +typedef int32_t (*IndexPreload)(GRD_DB *db, const char *collectionName); +typedef int32_t (*CreateCollection)(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags); +typedef int32_t (*DropCollection)(GRD_DB *db, const char *collectionName, uint32_t flags); +typedef int32_t (*InsertDoc)(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags); +typedef int32_t (*FindDoc)(GRD_DB *db, const char *collectionName, Query query, + uint32_t flags, GRD_ResultSet **resultSet); +typedef int32_t (*UpdateDoc)(GRD_DB *db, const char *collectionName, const char *filter, + const char *update, uint32_t flags); +typedef int32_t (*UpsertDoc)(GRD_DB *db, const char *collectionName, const char *filter, + const char *document, uint32_t flags); +typedef int32_t (*DeleteDoc)(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags); +typedef int32_t (*ResultNext)(GRD_ResultSet *resultSet); +typedef int32_t (*ResultPrev)(GRD_ResultSet *resultSet); +typedef int32_t (*GetValue)(GRD_ResultSet *resultSet, char **value); +typedef int32_t (*Fetch)(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value); +typedef int32_t (*FreeValue)(char *value); +typedef int32_t (*FreeResultSet)(GRD_ResultSet *resultSet); +typedef int32_t (*KVPut)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); +typedef int32_t (*KVGet)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); +typedef int32_t (*KVDel)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key); +typedef int32_t (*KVScan)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, KvScanModeE mode, + GRD_ResultSet **resultSet); +typedef int32_t (*KVFreeItem)(GRD_KVItemT *item); +typedef int32_t (*KVBatchPrepare)(uint16_t itemNum, GRD_KVBatchT **batch); +typedef int32_t ( + *KVBatchPushback)(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, GRD_KVBatchT *batch); +typedef int32_t (*KVBatchDel)(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch); +typedef int32_t (*KVBatchDestory)(GRD_KVBatchT *batch); +typedef int32_t (*CreateSeq)(GRD_DB *db, const char *sequenceName, uint32_t flags); +typedef int32_t (*DropSeq)(GRD_DB *db, const char *sequenceName, uint32_t flags); + +struct GRD_APIInfo { + DBOpen DBOpenApi = nullptr; + DBClose DBCloseApi = nullptr; + DBFlush FlushApi = nullptr; + IndexPreload IndexPreloadApi = nullptr; + CreateCollection CreateCollectionApi = nullptr; + DropCollection DropCollectionApi = nullptr; + InsertDoc InsertDocApi = nullptr; + FindDoc FindDocApi = nullptr; + UpdateDoc UpdateDocApi = nullptr; + UpsertDoc UpsertDocApi = nullptr; + DeleteDoc DeleteDocApi = nullptr; + ResultNext NextApi = nullptr; + ResultPrev PrevApi = nullptr; + GetValue GetValueApi = nullptr; + Fetch FetchApi = nullptr; + FreeValue FreeValueApi = nullptr; + FreeResultSet FreeResultSetApi = nullptr; + KVPut KVPutApi = nullptr; + KVGet KVGetApi = nullptr; + KVDel KVDelApi = nullptr; + KVScan KVScanApi = nullptr; + KVFreeItem KVFreeItemApi = nullptr; + KVBatchPrepare KVBatchPrepareApi = nullptr; + KVBatchPushback KVBatchPushbackApi = nullptr; + KVBatchDel KVBatchDelApi = nullptr; + KVBatchDestory KVBatchDestoryApi = nullptr; + CreateSeq CreateSeqApi = nullptr; + DropSeq DropSeqApi = nullptr; +}; +GRD_APIInfo GetApiInfoInstance(); +} // namespace DocumentDB +#endif // __cplusplus diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/json_common.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/json_common.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/json_common.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/json_common.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/log_print.h similarity index 92% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/log_print.h index 2b6774da15e9853b77b9d396bc252cddb16567eb..f02a6a8065c4c767f87053744af4a30267b88537 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/log_print.h @@ -35,7 +35,7 @@ public: }; } // namespace DocumentDB -#define NO_LOG(...) // No log in normal and release. Used for convenience when deep debugging +#define NO_LOG(...) // No log in normal and release. Used for the convenience when deep debugging #define GLOGD(...) LogPrint::Log(LogPrint::Level::LEVEL_DEBUG, LOG_TAG_DOC, __VA_ARGS__) #define GLOGI(...) LogPrint::Log(LogPrint::Level::LEVEL_INFO, LOG_TAG_DOC, __VA_ARGS__) #define GLOGW(...) LogPrint::Log(LogPrint::Level::LEVEL_WARN, LOG_TAG_DOC, __VA_ARGS__) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/os_api.h similarity index 88% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/os_api.h index e735edb95213855826e6e14d3231a322118a26c0..01f661c1b1aa3a3d1f9c16e6754fcbc72409a318 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/os_api.h @@ -19,9 +19,9 @@ namespace DocumentDB { namespace OSAPI { -bool CheckPermission(const std::string &filePath); +bool CheckPathPermission(const std::string &filePath); -bool CheckPathExistence(const std::string &filePath); +bool IsPathExist(const std::string &filePath); int GetRealPath(const std::string &inOriPath, std::string &outRealPath); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/collection_option.cpp similarity index 96% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/collection_option.cpp index d5310f73f78a580ed675f06c27ab48b302c5ac9b..06c0805efd030a5267e18bf6bc56fd95a97b33fa 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/collection_option.cpp @@ -26,7 +26,7 @@ namespace DocumentDB { namespace { constexpr const char *OPT_MAX_DOC = "maxdoc"; -int CheckConfigValid(const JsonObject &config) +int CFG_IsValid(const JsonObject &config) { JsonObject child = config.GetChild(); while (!child.IsNull()) { @@ -58,7 +58,7 @@ CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &er return {}; } - errCode = CheckConfigValid(collOpt); + errCode = CFG_IsValid(collOpt); if (errCode != E_OK) { GLOGE("Check collection option, not support config item. %d", errCode); return {}; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/db_config.cpp similarity index 96% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/db_config.cpp index 5061139eebd491f7adf5a1483d32523328320f42..661f55ced1557d1fdf1b8ed692f769efffe07f2a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/db_config.cpp @@ -42,7 +42,7 @@ constexpr const char *DB_CONFIG_BUFFER_POOL_SIZE = "bufferpoolsize"; constexpr const char *DB_CONFIG_CRC_CHECK_ENABLE = "crccheckenable"; const int DB_CONFIG_SIZE = 6; // db config size -const char *DB_CONFIG[DB_CONFIG_SIZE] = { DB_CONFIG_PAGESIZE, DB_CONFIG_REDO_FLUSH_BY_TRX, +const char *dbConfig[6] = { DB_CONFIG_PAGESIZE, DB_CONFIG_REDO_FLUSH_BY_TRX, // 6 is db config size DB_CONFIG_REDO_PUB_BUFF_SIZE, DB_CONFIG_MAX_CONN_NUM, DB_CONFIG_BUFFER_POOL_SIZE, DB_CONFIG_CRC_CHECK_ENABLE }; template @@ -125,14 +125,14 @@ bool CheckCrcCheckEnableConfig(const JsonObject &config, uint32_t &crcCheckEnabl return CheckAndGetDBConfig(config, DB_CONFIG_CRC_CHECK_ENABLE, checkFunction, crcCheckEnable); } -int CheckConfigValid(const JsonObject &config) +int CFG_IsValid(const JsonObject &config) { JsonObject child = config.GetChild(); while (!child.IsNull()) { std::string fieldName = child.GetItemField(); bool isSupport = false; for (int i = 0; i < DB_CONFIG_SIZE; i++) { - if (strcmp(DB_CONFIG[i], fieldName.c_str()) == 0) { + if (strcmp(dbConfig[i], fieldName.c_str()) == 0) { isSupport = true; break; } @@ -157,7 +157,7 @@ DBConfig DBConfig::GetDBConfigFromJsonStr(const std::string &confStr, int &errCo return {}; } - errCode = CheckConfigValid(dbConfig); + errCode = CFG_IsValid(dbConfig); if (errCode != E_OK) { GLOGE("Check DB config, not support config item. %d", errCode); return {}; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c75a891e1bf4868d814e24dc078bc2416faf703 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp @@ -0,0 +1,108 @@ +/* +* 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 "grd_api_manager.h" + +#include + +#include "check_common.h" +#include "doc_errno.h" +#include "document_store_manager.h" +#include "grd_base/grd_error.h" +#include "grd_db_api_inner.h" +#include "grd_document_api_inner.h" +#include "grd_kv_api_inner.h" +#include "grd_resultset_api_inner.h" +#include "grd_sequence_api_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" + +static void *g_library = nullptr; +namespace DocumentDB { +void GRD_DBApiInitCommon(GRD_APIInfo &GRD_DBApiInfo) +{ + GRD_DBApiInfo.DBOpenApi = GRD_DBOpenInner; + GRD_DBApiInfo.DBCloseApi = GRD_DBCloseInner; + GRD_DBApiInfo.FlushApi = GRD_FlushInner; + GRD_DBApiInfo.IndexPreloadApi = GRD_IndexPreloadInner; + GRD_DBApiInfo.CreateCollectionApi = GRD_CreateCollectionInner; + GRD_DBApiInfo.DropCollectionApi = GRD_DropCollectionInner; + GRD_DBApiInfo.InsertDocApi = GRD_InsertDocInner; + GRD_DBApiInfo.FindDocApi = GRD_FindDocInner; + GRD_DBApiInfo.UpdateDocApi = GRD_UpdateDocInner; + GRD_DBApiInfo.UpsertDocApi = GRD_UpsertDocInner; + GRD_DBApiInfo.DeleteDocApi = GRD_DeleteDocInner; + GRD_DBApiInfo.NextApi = GRD_NextInner; + GRD_DBApiInfo.PrevApi = GRD_PrevInner; + GRD_DBApiInfo.GetValueApi = GRD_GetValueInner; + GRD_DBApiInfo.FetchApi = GRD_FetchInner; + GRD_DBApiInfo.FreeValueApi = GRD_FreeValueInner; + GRD_DBApiInfo.FreeResultSetApi = GRD_FreeResultSetInner; + GRD_DBApiInfo.KVPutApi = GRD_KVPutInner; + GRD_DBApiInfo.KVGetApi = GRD_KVGetInner; + GRD_DBApiInfo.KVDelApi = GRD_KVDelInner; + GRD_DBApiInfo.KVScanApi = GRD_KVScanInner; + GRD_DBApiInfo.KVFreeItemApi = GRD_KVFreeItemInner; + GRD_DBApiInfo.KVBatchPrepareApi = GRD_KVBatchPrepareInner; + GRD_DBApiInfo.KVBatchPushbackApi = GRD_KVBatchPushbackInner; + GRD_DBApiInfo.KVBatchDelApi = GRD_KVBatchDelInner; + GRD_DBApiInfo.KVBatchDestoryApi = GRD_KVBatchDestoryInner; + GRD_DBApiInfo.CreateSeqApi = GRD_CreateSeqInner; + GRD_DBApiInfo.DropSeqApi = GRD_DropSeqInner; +} + +void GRD_DBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) +{ + GRD_DBApiInfo.DBOpenApi = (DBOpen)dlsym(g_library, "GRD_DBOpen"); + GRD_DBApiInfo.DBCloseApi = (DBClose)dlsym(g_library, "GRD_DBClose"); + GRD_DBApiInfo.FlushApi = (DBFlush)dlsym(g_library, "GRD_Flush"); + GRD_DBApiInfo.IndexPreloadApi = (IndexPreload)dlsym(g_library, "GRD_IndexPreload"); + GRD_DBApiInfo.CreateCollectionApi = (CreateCollection)dlsym(g_library, "GRD_CreateCollection"); + GRD_DBApiInfo.DropCollectionApi = (DropCollection)dlsym(g_library, "GRD_DropCollection"); + GRD_DBApiInfo.InsertDocApi = (InsertDoc)dlsym(g_library, "GRD_InsertDoc"); + GRD_DBApiInfo.FindDocApi = (FindDoc)dlsym(g_library, "GRD_FindDoc"); + GRD_DBApiInfo.UpdateDocApi = (UpdateDoc)dlsym(g_library, "GRD_UpdateDoc"); + GRD_DBApiInfo.UpsertDocApi = (UpsertDoc)dlsym(g_library, "GRD_UpsertDoc"); + GRD_DBApiInfo.DeleteDocApi = (DeleteDoc)dlsym(g_library, "GRD_DeleteDoc"); + GRD_DBApiInfo.NextApi = (ResultNext)dlsym(g_library, "GRD_Next"); + GRD_DBApiInfo.PrevApi = (ResultPrev)dlsym(g_library, "GRD_Prev"); + GRD_DBApiInfo.GetValueApi = (GetValue)dlsym(g_library, "GRD_GetValue"); + GRD_DBApiInfo.FetchApi = (Fetch)dlsym(g_library, "GRD_Fetch"); + GRD_DBApiInfo.FreeValueApi = (FreeValue)dlsym(g_library, "GRD_FreeValue"); + GRD_DBApiInfo.FreeResultSetApi = (FreeResultSet)dlsym(g_library, "GRD_FreeResultSet"); + GRD_DBApiInfo.KVPutApi = (KVPut)dlsym(g_library, "GRD_KVPut"); + GRD_DBApiInfo.KVGetApi = (KVGet)dlsym(g_library, "GRD_KVGet"); + GRD_DBApiInfo.KVDelApi = (KVDel)dlsym(g_library, "GRD_KVDel"); + GRD_DBApiInfo.KVScanApi = (KVScan)dlsym(g_library, "GRD_KVScan"); + GRD_DBApiInfo.KVFreeItemApi = (KVFreeItem)dlsym(g_library, "GRD_KVFreeItem"); + GRD_DBApiInfo.KVBatchPrepareApi = (KVBatchPrepare)dlsym(g_library, "GRD_KVBatchPrepare"); + GRD_DBApiInfo.KVBatchPushbackApi = (KVBatchPushback)dlsym(g_library, "GRD_KVBatchPushback"); + GRD_DBApiInfo.KVBatchDelApi = (KVBatchDel)dlsym(g_library, "GRD_KVBatchDel"); + GRD_DBApiInfo.KVBatchDestoryApi = (KVBatchDestory)dlsym(g_library, "GRD_KVBatchDestory"); + GRD_DBApiInfo.CreateSeqApi = (CreateSeq)dlsym(g_library, "GRD_CreateSeq"); + GRD_DBApiInfo.DropSeqApi = (DropSeq)dlsym(g_library, "GRD_DropSeq"); +} + +GRD_APIInfo GetApiInfoInstance() +{ + GRD_APIInfo GRD_TempApiStruct; + g_library = dlopen("/system/lib64/libgaussdb_rd.z.so", RTLD_LAZY); + if (!g_library) { + GRD_DBApiInitCommon(GRD_TempApiStruct); // When calling specific function, read whether init is successful. + } else { + GRD_DBApiInitEnhance(GRD_TempApiStruct); + } + return GRD_TempApiStruct; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/json_common.cpp similarity index 98% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/json_common.cpp index a967d2e69125bd45aa34a6d47f1abba381eea4e8..95499f9650cbb6ffbd97918107b5827735f234ca 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/json_common.cpp @@ -245,7 +245,7 @@ std::vector> JsonCommon::ParsePath(const JsonObject &ro namespace { JsonFieldPath SplitePath(const JsonFieldPath &path, bool &isCollapse) { - if (path.size() > 1 || path.empty()) { // only first level has collapse field + if (path.size() != 1) { // only first level has collapse field return path; } JsonFieldPath splitPath; @@ -266,6 +266,9 @@ JsonFieldPath SplitePath(const JsonFieldPath &path, bool &isCollapse) JsonFieldPath ExpendPathForField(const JsonFieldPath &path, bool &isCollapse) { JsonFieldPath splitPath; + if (path.empty()) { + return path; + } const std::string &str = path.back(); size_t start = 0; size_t end = 0; @@ -283,7 +286,7 @@ JsonFieldPath ExpendPathForField(const JsonFieldPath &path, bool &isCollapse) return splitPath; } -void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, +void JsonObjectIterator(const JsonObject &obj, const JsonFieldPath &path, std::function AppendFoo) { JsonObject child = obj.GetChild(); @@ -298,14 +301,14 @@ void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, } void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, - std::function MatchFoo) + std::function matchFoo) { JsonObject child = obj.GetChild(); while (!child.IsNull()) { JsonFieldPath childPath = path; childPath.push_back(child.GetItemField()); - if (MatchFoo != nullptr && MatchFoo(childPath, child)) { - JsonObjectIterator(child, childPath, MatchFoo); + if (matchFoo != nullptr && matchFoo(childPath, child)) { + JsonObjectIterator(child, childPath, matchFoo); } child = child.GetNext(); } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/log_print.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/log_print.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/log_print.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/log_print.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp similarity index 94% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp index 8374915d78292a97c1f1988ae7b563c30797407c..c8a1338851d72e11836dfea7b25fab01573bd31e 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp @@ -27,12 +27,12 @@ namespace { const int ACCESS_MODE_EXISTENCE = 0; } namespace OSAPI { -bool CheckPermission(const std::string &filePath) +bool CheckPathPermission(const std::string &filePath) { return (access(filePath.c_str(), R_OK) == 0) && (access(filePath.c_str(), W_OK) == 0); } -bool CheckPathExistence(const std::string &filePath) +bool IsPathExist(const std::string &filePath) { return (access(filePath.c_str(), ACCESS_MODE_EXISTENCE) == 0); } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc8563594e1c39565c4ab89b1bfa04a1b57abf7c --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp @@ -0,0 +1,60 @@ +/* +* 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 "grd_base/grd_db_api.h" + +#include + +#include "check_common.h" +#include "doc_errno.h" +#include "document_store_manager.h" +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_type_inner.h" +#include "log_print.h" + +using namespace DocumentDB; +static GRD_APIInfo GRD_DBApiInfo = GetApiInfoInstance(); + +GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db) +{ + if (GRD_DBApiInfo.DBOpenApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DBApiInfo.DBOpenApi(dbPath, configStr, flags, db); +} + +GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags) +{ + if (GRD_DBApiInfo.DBCloseApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DBApiInfo.DBCloseApi(db, flags); +} + +GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags) +{ + if (GRD_DBApiInfo.FlushApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DBApiInfo.FlushApi(db, flags); +} + +GRD_API int32_t GRD_IndexPreload(GRD_DB *db, const char *collectionName) +{ + if (GRD_DBApiInfo.IndexPreloadApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DBApiInfo.IndexPreloadApi(db, collectionName); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp similarity index 80% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp index f61b9ffc616a6ab4f2288087a7f2ff124cd97cd4..2aa5ba54ab06e2e22b62fc6d68c42eddc447bbdc 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp @@ -12,18 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "grd_base/grd_db_api.h" - +#include +#include "grd_db_api_inner.h" +#include "check_common.h" #include "doc_errno.h" #include "document_store_manager.h" +#include "grd_api_manager.h" #include "grd_base/grd_error.h" #include "grd_type_inner.h" #include "log_print.h" -using namespace DocumentDB; - -GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db) +namespace DocumentDB { +int32_t GRD_DBOpenInner(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db) { if (db == nullptr) { return GRD_INVALID_ARGS; @@ -47,7 +47,7 @@ GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t f return TransferDocErr(ret); } -GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags) +int32_t GRD_DBCloseInner(GRD_DB *db, uint32_t flags) { if (db == nullptr || db->store_ == nullptr) { return GRD_INVALID_ARGS; @@ -63,7 +63,7 @@ GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags) return GRD_OK; } -GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags) +int32_t GRD_FlushInner(GRD_DB *db, uint32_t flags) { if (db == nullptr || db->store_ == nullptr) { return GRD_INVALID_ARGS; @@ -72,4 +72,10 @@ GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags) return GRD_INVALID_ARGS; } return GRD_OK; -} \ No newline at end of file +} + +int32_t GRD_IndexPreloadInner(GRD_DB *db, const char *collectionName) +{ + return GRD_OK; // No support; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.cpp similarity index 76% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.cpp index e4af38a11e9946aead164b1a673f693ee652f5a7..316e2e7e2f5654fa66d0cafae50e655f790394b5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.cpp @@ -18,9 +18,11 @@ #include #include "doc_errno.h" +#include "grd_base/grd_db_api.h" #include "log_print.h" #include "securec.h" +using namespace DocumentDB; namespace DocumentDB { namespace { constexpr const char *KEY_ID = "_id"; @@ -41,7 +43,7 @@ bool CheckCollectionNamePrefix(const std::string &name, const std::string &prefi void ReplaceAll(std::string &inout, const std::string &what, const std::string &with) { - std::string::size_type pos {}; + std::string::size_type pos{}; while ((pos = inout.find(what.data(), pos, what.length())) != std::string::npos) { inout.replace(pos, what.length(), with.data(), with.length()); pos += with.length(); @@ -75,6 +77,27 @@ bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::st return true; } +static int CheckSingleFilterPath(std::vector &singleFilterPath) +{ + if (singleFilterPath.empty()) { + return -E_INVALID_JSON_FORMAT; + } + for (size_t j = 0; j < singleFilterPath.size(); j++) { + if (singleFilterPath[j].empty()) { + return -E_INVALID_ARGS; + } + for (auto oneChar : singleFilterPath[j]) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return -E_INVALID_ARGS; + } + } + } + if (!singleFilterPath.empty() && !singleFilterPath[0].empty() && isdigit(singleFilterPath[0][0])) { + return -E_INVALID_ARGS; + } + return E_OK; +} + int CheckCommon::CheckFilter(JsonObject &filterObj, std::vector> &filterPath, bool &isIdExist) { for (size_t i = 0; i < filterPath.size(); i++) { @@ -83,30 +106,19 @@ int CheckCommon::CheckFilter(JsonObject &filterObj, std::vector &allFi return E_OK; } +static int CheckSingleUpdataDocPath(std::vector &singleUpdataPath) +{ + for (const auto &fieldName : singleUpdataPath) { + for (auto oneChar : fieldName) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + GLOGE("updata fieldName is illegal"); + return -E_INVALID_ARGS; + } + } + } + return E_OK; +} + int CheckCommon::CheckUpdata(JsonObject &updataObj) { JsonObject jsonTemp = updataObj.GetChild(); @@ -173,13 +198,9 @@ int CheckCommon::CheckUpdata(JsonObject &updataObj) if (errCode != E_OK) { return errCode; } - for (const auto &fieldName : allFieldsName) { - for (auto oneChar : fieldName) { - if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { - GLOGE("updata fieldName is illegal"); - return -E_INVALID_ARGS; - } - } + errCode = CheckSingleUpdataDocPath(allFieldsName); + if (errCode != E_OK) { + return errCode; } maxDeep = std::max(allFieldsName.size() + jsonTemp.GetDeep(), maxDeep); if (maxDeep > JSON_DEEP_MAX) { @@ -196,6 +217,24 @@ int CheckCommon::CheckUpdata(JsonObject &updataObj) return E_OK; } +static int CheckSingleProjectionDocPath(std::vector &singleProjectionPath) +{ + for (const auto &fieldName : singleProjectionPath) { + if (fieldName.empty()) { + return -E_INVALID_ARGS; + } + for (size_t j = 0; j < fieldName.size(); j++) { + if (!((isalpha(fieldName[j])) || (isdigit(fieldName[j])) || (fieldName[j] == '_'))) { + return -E_INVALID_ARGS; + } + if (j == 0 && (isdigit(fieldName[j]))) { + return -E_INVALID_ARGS; + } + } + } + return E_OK; +} + int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &path) { if (projectionObj.GetDeep() > JSON_DEEP_MAX) { @@ -214,18 +253,9 @@ int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &path); + static bool checkIsApiInit(); }; using Key = std::vector; using Value = std::vector; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a30d919defd41d8f446972bcd74289df1f56eef1 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp @@ -0,0 +1,85 @@ +/* +* 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 "grd_document/grd_document_api.h" + +#include "check_common.h" +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_resultset_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" +using namespace DocumentDB; + +static GRD_APIInfo GRD_DocApiInfo = GetApiInfoInstance(); + +GRD_API int32_t GRD_CreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags) +{ + if (GRD_DocApiInfo.CreateCollectionApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.CreateCollectionApi(db, collectionName, optionStr, flags); +} + +GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint32_t flags) +{ + if (GRD_DocApiInfo.DropCollectionApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.DropCollectionApi(db, collectionName, flags); +} + +GRD_API int32_t GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *update, + uint32_t flags) +{ + if (GRD_DocApiInfo.UpdateDocApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.UpdateDocApi(db, collectionName, filter, update, flags); +} + +GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *document, + uint32_t flags) +{ + if (GRD_DocApiInfo.UpsertDocApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.UpsertDocApi(db, collectionName, filter, document, flags); +} + +GRD_API int32_t GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags) +{ + if (GRD_DocApiInfo.InsertDocApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.InsertDocApi(db, collectionName, document, flags); +} + +GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags) +{ + if (GRD_DocApiInfo.DeleteDocApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.DeleteDocApi(db, collectionName, filter, flags); +} + +GRD_API int32_t GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, uint32_t flags, + GRD_ResultSet **resultSet) +{ + if (GRD_DocApiInfo.FindDocApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_DocApiInfo.FindDocApi(db, collectionName, query, flags, resultSet); +} diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp similarity index 78% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp index 701ad17e7bad1919971fb7b22873276b683a7d0e..13b50c042c467289c78f050d6ea8199185b518c9 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp @@ -13,15 +13,16 @@ * limitations under the License. */ -#include "grd_document/grd_document_api.h" - +#include "check_common.h" +#include "grd_api_manager.h" +#include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" +#include "grd_document_api_inner.h" #include "grd_resultset_inner.h" #include "grd_type_inner.h" #include "log_print.h" -using namespace DocumentDB; - -GRD_API int32_t GRD_CreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags) +namespace DocumentDB { +int32_t GRD_CreateCollectionInner(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags) { if (db == nullptr || db->store_ == nullptr) { return GRD_INVALID_ARGS; @@ -33,7 +34,7 @@ GRD_API int32_t GRD_CreateCollection(GRD_DB *db, const char *collectionName, con return TransferDocErr(ret); } -GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint32_t flags) +int32_t GRD_DropCollectionInner(GRD_DB *db, const char *collectionName, uint32_t flags) { if (db == nullptr || db->store_ == nullptr) { return GRD_INVALID_ARGS; @@ -44,7 +45,7 @@ GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint3 return TransferDocErr(ret); } -GRD_API int32_t GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *update, +int32_t GRD_UpdateDocInner(GRD_DB *db, const char *collectionName, const char *filter, const char *update, uint32_t flags) { if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || filter == nullptr || update == nullptr) { @@ -57,7 +58,7 @@ GRD_API int32_t GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char return TransferDocErr(ret); } -GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *document, +int32_t GRD_UpsertDocInner(GRD_DB *db, const char *collectionName, const char *filter, const char *document, uint32_t flags) { if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || filter == nullptr || @@ -71,7 +72,7 @@ GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char return TransferDocErr(ret); } -GRD_API int32_t GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags) +int32_t GRD_InsertDocInner(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags) { if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || document == nullptr) { return GRD_INVALID_ARGS; @@ -80,7 +81,7 @@ GRD_API int32_t GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char return TransferDocErr(ret); } -GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags) +int32_t GRD_DeleteDocInner(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags) { if (db == nullptr || db->store_ == nullptr || filter == nullptr || collectionName == nullptr) { return GRD_INVALID_ARGS; @@ -97,8 +98,7 @@ GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char } } -GRD_API int32_t GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, uint32_t flags, - GRD_ResultSet **resultSet) +int32_t GRD_FindDocInner(GRD_DB *db, const char *collectionName, Query query, uint32_t flags, GRD_ResultSet **resultSet) { if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || resultSet == nullptr || query.filter == nullptr || query.projection == nullptr) { @@ -117,3 +117,4 @@ GRD_API int32_t GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, *resultSet = grdResultSet; return TransferDocErr(ret); } +} // namespace DocumentDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..837fd545dafa7327feeeecd4384337f5546675a1 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp @@ -0,0 +1,72 @@ +/* +* 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 "grd_base/grd_resultset_api.h" + +#include "doc_errno.h" +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_resultset_inner.h" +#include "log_print.h" + +using namespace DocumentDB; +static GRD_APIInfo GRD_ResultSetApiInfo = GetApiInfoInstance(); + +GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet) +{ + if (GRD_ResultSetApiInfo.NextApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.NextApi(resultSet); +} + +GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value) +{ + if (GRD_ResultSetApiInfo.GetValueApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.GetValueApi(resultSet, value); +} + +GRD_API int32_t GRD_FreeValue(char *value) +{ + if (GRD_ResultSetApiInfo.FreeValueApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.FreeValueApi(value); +} + +GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet) +{ + if (GRD_ResultSetApiInfo.FreeResultSetApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.FreeResultSetApi(resultSet); +} + +GRD_API int32_t GRD_Prev(GRD_ResultSet *resultSet) +{ + if (GRD_ResultSetApiInfo.PrevApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.PrevApi(resultSet); +} + +GRD_API int32_t GRD_Fetch(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value) +{ + if (GRD_ResultSetApiInfo.FetchApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_ResultSetApiInfo.FetchApi(resultSet, key, value); +} diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp similarity index 74% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp index d529552f9d1bacaefe7803050d14a6fd90b4817b..9027d7bb77095dc6389510d87ab653c32063a43d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp @@ -12,18 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "grd_base/grd_resultset_api.h" - -#include - #include "doc_errno.h" +#include "grd_api_manager.h" #include "grd_base/grd_error.h" +#include "grd_resultset_api_inner.h" #include "grd_resultset_inner.h" #include "log_print.h" -using namespace DocumentDB; - -GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet) +namespace DocumentDB { +int32_t GRD_NextInner(GRD_ResultSet *resultSet) { if (resultSet == nullptr) { GLOGE("resultSet is nullptr"); @@ -33,7 +30,7 @@ GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet) return TransferDocErr(ret); } -GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value) +int32_t GRD_GetValueInner(GRD_ResultSet *resultSet, char **value) { if (resultSet == nullptr || value == nullptr) { GLOGE("resultSet is nullptr,cant get value from it"); @@ -49,7 +46,7 @@ GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value) return TransferDocErr(ret); } -GRD_API int32_t GRD_FreeValue(char *value) +int32_t GRD_FreeValueInner(char *value) { if (value == nullptr) { return GRD_INVALID_ARGS; @@ -58,7 +55,7 @@ GRD_API int32_t GRD_FreeValue(char *value) return GRD_OK; } -GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet) +int32_t GRD_FreeResultSetInner(GRD_ResultSet *resultSet) { if (resultSet == nullptr) { return GRD_INVALID_ARGS; @@ -66,4 +63,15 @@ GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet) resultSet->resultSet_.EraseCollection(); delete resultSet; return GRD_OK; -} \ No newline at end of file +} + +int32_t GRD_PrevInner(GRD_ResultSet *resultSet) +{ + return GRD_OK; // No support; +} + +int32_t GRD_FetchInner(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value) +{ + return GRD_OK; // No support; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_db_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_db_api_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..0aafa77506d217a8262e9f3a7ce0e4d616325c3e --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_db_api_inner.h @@ -0,0 +1,29 @@ +/* +* 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 GRD_DB_API_INNER_H +#define GRD_DB_API_INNER_H +#include +#include "grd_base/grd_type_export.h" +namespace DocumentDB { +int32_t GRD_DBOpenInner(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db); + +int32_t GRD_DBCloseInner(GRD_DB *db, uint32_t flags); + +int32_t GRD_IndexPreloadInner(GRD_DB *db, const char *collectionName); + +int32_t GRD_FlushInner(GRD_DB *db, uint32_t flags); +} // namespace DocumentDB +#endif // GRD_DB_API_INNER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_document_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_document_api_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..4011ede6107f8f76e2b68b44b85eb15b708eee36 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_document_api_inner.h @@ -0,0 +1,42 @@ +/* +* 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 GRD_DOCUMENT_API_INNER_H +#define GRD_DOCUMENT_API_INNER_H + +#include + +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" + +namespace DocumentDB { +int32_t GRD_CreateCollectionInner(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags); + +int32_t GRD_DropCollectionInner(GRD_DB *db, const char *collectionName, uint32_t flags); + +int32_t GRD_InsertDocInner(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags); + +int32_t GRD_FindDocInner(GRD_DB *db, const char *collectionName, Query query, uint32_t flags, + GRD_ResultSet **resultSet); + +int32_t GRD_UpdateDocInner(GRD_DB *db, const char *collectionName, const char *filter, const char *update, + uint32_t flags); + +int32_t GRD_UpsertDocInner(GRD_DB *db, const char *collectionName, const char *filter, const char *document, + uint32_t flags); + +int32_t GRD_DeleteDocInner(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags); +} // namespace DocumentDB +#endif // GRD_DOCUMENT_API_INNER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_format_config.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_format_config.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_format_config.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_format_config.h diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..f4d1754801ad3c29de179dffdb5287079168c301 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h @@ -0,0 +1,45 @@ +/* +* 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 GRD_KV_API_INNER_H +#define GRD_KV_API_INNER_H + +#include + +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" + +namespace DocumentDB { +int32_t GRD_KVPutInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); + +int32_t GRD_KVGetInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value); + +int32_t GRD_KVDelInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key); + +int32_t GRD_KVScanInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, KvScanModeE mode, + GRD_ResultSet **resultSet); + +int32_t GRD_KVFreeItemInner(GRD_KVItemT *item); + +int32_t GRD_KVBatchPrepareInner(uint16_t itemNum, GRD_KVBatchT **batch); + +int32_t GRD_KVBatchPushbackInner(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, + GRD_KVBatchT *batch); + +int32_t GRD_KVBatchDelInner(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch); + +int32_t GRD_KVBatchDestoryInner(GRD_KVBatchT *batch); +} // namespace DocumentDB +#endif // GRD_KV_API_INNER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_resultset_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_resultset_api_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..6c4ca6811b5a5a18c8d79ff03924fdc4b539f742 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_resultset_api_inner.h @@ -0,0 +1,37 @@ +/* +* 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 GRD_RESULTSET_API_INNER_H +#define GRD_RESULTSET_API_INNER_H + +#include + +#include "grd_base/grd_type_export.h" + +namespace DocumentDB { +typedef struct GRD_ResultSet GRD_ResultSet; +int32_t GRD_NextInner(GRD_ResultSet *resultSet); + +int32_t GRD_PrevInner(GRD_ResultSet *resultSet); + +int32_t GRD_GetValueInner(GRD_ResultSet *resultSet, char **value); + +int32_t GRD_FetchInner(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value); + +int32_t GRD_FreeValueInner(char *value); + +int32_t GRD_FreeResultSetInner(GRD_ResultSet *resultSet); +} // namespace DocumentDB +#endif // GRD_RESULTSET_API_INNER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_resultset_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_resultset_inner.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_resultset_inner.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_resultset_inner.h diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_sequence_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_sequence_api_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..072f55e238b70ba0c3df0ccbbaf2f336fc8e0d1e --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_sequence_api_inner.h @@ -0,0 +1,29 @@ +/* +* 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 GRD_SEQUENCE_API_INNER_H +#define GRD_SEQUENCE_API_INNER_H + +#include + +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" + +namespace DocumentDB { +int32_t GRD_CreateSeqInner(GRD_DB *db, const char *sequenceName, uint32_t flags); + +int32_t GRD_DropSeqInner(GRD_DB *db, const char *sequenceName, uint32_t flags); +} // namespace DocumentDB +#endif // GRD_SEQUENCE_API_INNER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_type_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_type_inner.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_type_inner.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_type_inner.h diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b806106e781b2b857c57fe99ca163ebce06b0e4 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp @@ -0,0 +1,98 @@ +/* +* 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 "grd_kv/grd_kv_api.h" + +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_resultset_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" +using namespace DocumentDB; + +static GRD_APIInfo GRD_KVApiInfo = GetApiInfoInstance(); + +GRD_API int32_t GRD_KVPut(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) +{ + if (GRD_KVApiInfo.KVPutApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVPutApi(db, collectionName, key, value); +} + +GRD_API int32_t GRD_KVGet(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) +{ + if (GRD_KVApiInfo.KVGetApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVGetApi(db, collectionName, key, value); +} + +GRD_API int32_t GRD_KVDel(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key) +{ + if (GRD_KVApiInfo.KVDelApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVDelApi(db, collectionName, key); +} + +GRD_API int32_t GRD_KVScan(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, KvScanModeE mode, + GRD_ResultSet **resultSet) +{ + if (GRD_KVApiInfo.KVScanApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVScanApi(db, collectionName, key, mode, resultSet); +} + +GRD_API int32_t GRD_KVFreeItem(GRD_KVItemT *item) +{ + if (GRD_KVApiInfo.KVFreeItemApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVFreeItemApi(item); +} + +GRD_API int32_t GRD_KVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch) +{ + if (GRD_KVApiInfo.KVBatchPrepareApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVBatchPrepareApi(itemNum, batch); +} + +GRD_API int32_t GRD_KVBatchPushback(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, + GRD_KVBatchT *batch) +{ + if (GRD_KVApiInfo.KVBatchPushbackApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVBatchPushbackApi(key, keyLen, data, dataLen, batch); +} + +GRD_API int32_t GRD_KVBatchDel(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch) +{ + if (GRD_KVApiInfo.KVBatchDelApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVBatchDelApi(db, collectionName, batch); +} + +GRD_API int32_t GRD_KVBatchDestory(GRD_KVBatchT *batch) +{ + if (GRD_KVApiInfo.KVBatchDestoryApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVBatchDestoryApi(batch); +} diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a470ef2e1dd58bb60c7a72f33382369a4a66c091 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp @@ -0,0 +1,68 @@ +/* +* 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 "check_common.h" +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_kv_api_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" +namespace DocumentDB { +int32_t GRD_KVPutInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVGetInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVDelInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVScanInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, KvScanModeE mode, + GRD_ResultSet **resultSet) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVFreeItemInner(GRD_KVItemT *item) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVBatchPrepareInner(uint16_t itemNum, GRD_KVBatchT **batch) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVBatchPushbackInner(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, + GRD_KVBatchT *batch) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVBatchDelInner(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_KVBatchDestoryInner(GRD_KVBatchT *batch) +{ + return GRD_NOT_SUPPORT; // No support. +} +} // namespace DocumentDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bfb8723431072d015fcae94b6d64016efd2abb4f --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api.cpp @@ -0,0 +1,37 @@ +/* +* 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 "grd_shared_obj/grd_sequence_api.h" + +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_type_inner.h" +#include "log_print.h" +using namespace DocumentDB; +static GRD_APIInfo GRD_SeqApiInfo = GetApiInfoInstance(); +GRD_API int32_t GRD_CreateSeq(GRD_DB *db, const char *sequenceName, uint32_t flags) +{ + if (GRD_SeqApiInfo.CreateSeqApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_SeqApiInfo.CreateSeqApi(db, sequenceName, flags); +} + +GRD_API int32_t GRD_DropSeq(GRD_DB *db, const char *sequenceName, uint32_t flags) +{ + if (GRD_SeqApiInfo.DropSeqApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_SeqApiInfo.DropSeqApi(db, sequenceName, flags); +} diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api_inner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17e71400af7d3593407347717d2cdd9327bfdac5 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/shared_obj/grd_sequence_api_inner.cpp @@ -0,0 +1,31 @@ +/* +* 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 "check_common.h" +#include "grd_api_manager.h" +#include "grd_base/grd_error.h" +#include "grd_sequence_api_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" +namespace DocumentDB { +int32_t GRD_CreateSeqInner(GRD_DB *db, const char *sequenceName, uint32_t flags) +{ + return GRD_NOT_SUPPORT; // No support. +} + +int32_t GRD_DropSeqInner(GRD_DB *db, const char *sequenceName, uint32_t flags) +{ + return GRD_NOT_SUPPORT; // No support. +} +} // namespace DocumentDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/collection.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/collection.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/doc_errno.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/doc_errno.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_key.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_key.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_store.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_store.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store_manager.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_store_manager.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store_manager.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/document_store_manager.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/projection_tree.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/projection_tree.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/result_set.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/result_set.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/result_set_common.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/include/result_set_common.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/doc_errno.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/doc_errno.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_store.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_store.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_store_manager.cpp similarity index 96% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_store_manager.cpp index 138c86ab99caf2062b166fd4350508b56684b05e..5e306156c18630a11be424ec83566ce421e623fb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_store_manager.cpp @@ -38,7 +38,7 @@ bool CheckDBCloseFlag(unsigned int flag) bool CheckDBCreate(uint32_t flags, const std::string &path) { - if ((flags & GRD_DB_OPEN_CREATE) == 0 && !OSAPI::CheckPathExistence(path)) { + if ((flags & GRD_DB_OPEN_CREATE) == 0 && !OSAPI::IsPathExist(path)) { return false; } return true; @@ -145,7 +145,7 @@ int DocumentStoreManager::CheckDBPath(const std::string &path, std::string &cano return -E_FILE_OPERATION; } - if (!OSAPI::CheckPermission(canonicalPath)) { + if (!OSAPI::CheckPathPermission(canonicalPath)) { GLOGE("Check path permission failed."); return -E_FILE_OPERATION; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp similarity index 57% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp index 4ab699c391b76942f6a9512b545c408308f9ebd3..acd2862f0ccc7ed6b377cdd46edfee7e8638204e 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp @@ -17,6 +17,35 @@ namespace DocumentDB { constexpr int JSON_DEEP_MAX = 4; +static int ParseSinglePathToTree(ProjectionNode *node, std::vector &singlePath) +{ + for (size_t j = 0; j < singlePath.size(); j++) { + if (node->sonNode[singlePath[j]] != nullptr) { + node = node->sonNode[singlePath[j]]; + if (j < singlePath.size() - 1 && node->isDeepest) { + return -E_INVALID_ARGS; + } + if (j == singlePath.size() - 1 && !node->isDeepest) { + return -E_INVALID_ARGS; + } + } else { + auto tempNode = new (std::nothrow) ProjectionNode; + if (tempNode == nullptr) { + GLOGE("Memory allocation failed!"); + return -E_FAILED_MEMORY_ALLOCATE; + } + tempNode->Deep = node->Deep + 1; + if (tempNode->Deep > JSON_DEEP_MAX) { + delete tempNode; + return -E_INVALID_ARGS; + } + node->isDeepest = false; + node->sonNode[singlePath[j]] = tempNode; + node = node->sonNode[singlePath[j]]; + } + } + return E_OK; +} int ProjectionTree::ParseTree(std::vector> &path) { ProjectionNode *node = &node_; @@ -25,30 +54,9 @@ int ProjectionTree::ParseTree(std::vector> &path) } for (auto singlePath : path) { node = &node_; - for (size_t j = 0; j < singlePath.size(); j++) { - if (node->sonNode[singlePath[j]] != nullptr) { - node = node->sonNode[singlePath[j]]; - if (j < singlePath.size() - 1 && node->isDeepest) { - return -E_INVALID_ARGS; - } - if (j == singlePath.size() - 1 && !node->isDeepest) { - return -E_INVALID_ARGS; - } - } else { - auto tempNode = new (std::nothrow) ProjectionNode; - if (tempNode == nullptr) { - GLOGE("Memory allocation failed!"); - return -E_FAILED_MEMORY_ALLOCATE; - } - tempNode->Deep = node->Deep + 1; - if (tempNode->Deep > JSON_DEEP_MAX) { - delete tempNode; - return -E_INVALID_ARGS; - } - node->isDeepest = false; - node->sonNode[singlePath[j]] = tempNode; - node = node->sonNode[singlePath[j]]; - } + int errCode = ParseSinglePathToTree(node, singlePath); + if (errCode != E_OK) { + return errCode; } } return E_OK; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set_common.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set_common.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/json_object.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/json_object.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/json_object.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/json_object.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn similarity index 91% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn index c8a7cab5bef9293c572812296e3c230be15dd291..13f0f8b1d4740cd46a5cc9c86db56be9489c8149 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn @@ -12,7 +12,7 @@ # limitations under the License. import("//build/test.gni") -module_output_path = "datamgr_service/gaussdb_rd" +module_output_path = "kv_store/gaussdb_rd" ############################################################################### config("module_private_config") { @@ -47,14 +47,21 @@ ohos_source_set("src_file") { sources = [ "../../src/common/src/collection_option.cpp", "../../src/common/src/db_config.cpp", - "../../src/common/src/db_constant.cpp", + "../../src/common/src/grd_api_manager.cpp", "../../src/common/src/json_common.cpp", "../../src/common/src/log_print.cpp", "../../src/common/src/os_api.cpp", "../../src/executor/base/grd_db_api.cpp", + "../../src/executor/base/grd_db_api_inner.cpp", "../../src/executor/document/check_common.cpp", "../../src/executor/document/grd_document_api.cpp", + "../../src/executor/document/grd_document_api_inner.cpp", "../../src/executor/document/grd_resultset_api.cpp", + "../../src/executor/document/grd_resultset_api_inner.cpp", + "../../src/executor/kv/grd_kv_api.cpp", + "../../src/executor/kv/grd_kv_api_inner.cpp", + "../../src/executor/shared_obj/grd_sequence_api.cpp", + "../../src/executor/shared_obj/grd_sequence_api_inner.cpp", "../../src/interface/src/collection.cpp", "../../src/interface/src/doc_errno.cpp", "../../src/interface/src/document_key.cpp", @@ -88,7 +95,7 @@ ohos_source_set("src_file") { ] subsystem_name = "distributeddatamgr" - part_name = "datamgr_service" + part_name = "kv_store" } template("gaussdb_rd_unittest") { diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp similarity index 99% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp index 820667f7e9a25acbe787c5ea0e23184358de49b4..ee7e8dcfaec328fe4dd6dd8baf3ec910a9ac3ed3 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp @@ -60,17 +60,19 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest001, TestSize.Level0) std::string path = "./document.db"; GRD_DB *db = nullptr; int status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); + printf("mazhao work here aaa"); EXPECT_EQ(status, GRD_OK); EXPECT_NE(db, nullptr); GLOGD("Open DB test 001: status: %d", status); EXPECT_EQ(GRD_CreateCollection(db, "student", "", 0), GRD_OK); - + printf("mazhao work here bbb"); EXPECT_EQ(GRD_UpsertDoc(db, "student", R""({"_id":"10001"})"", R""({"name":"Tom", "age":23})"", 0), 1); - + printf("mazhao work here ccc"); EXPECT_EQ(GRD_DropCollection(db, "student", 0), GRD_OK); - + printf("mazhao work here ddd"); status = GRD_DBClose(db, GRD_DB_CLOSE); + printf("mazhao work here eee"); EXPECT_EQ(status, GRD_OK); db = nullptr; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_test_utils.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_test_utils.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_test_utils.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/api/documentdb_test_utils.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/common/documentdb_test_utils.h similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.h rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/common/documentdb_test_utils.h diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp similarity index 100% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp rename to kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp diff --git a/kv_store/frameworks/libs/distributeddb/include/query.h b/kv_store/frameworks/libs/distributeddb/include/query.h index dbc6aae4c6a2d730d5f3d3ec00d3f6aba58b14cd..25821e237db6e01573b230c4ca9ddd0336ae1585 100644 --- a/kv_store/frameworks/libs/distributeddb/include/query.h +++ b/kv_store/frameworks/libs/distributeddb/include/query.h @@ -35,13 +35,14 @@ public: DB_API Query &FromTable(const std::vector &tableNames); + DB_API Query &From(const std::string &tableName); + template DB_API Query &EqualTo(const std::string &field, const T &value) { FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::EQUALTO, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -51,7 +52,6 @@ public: FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::NOT_EQUALTO, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -61,7 +61,6 @@ public: FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::GREATER_THAN, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -71,7 +70,6 @@ public: FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::LESS_THAN, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -81,7 +79,6 @@ public: FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::GREATER_THAN_OR_EQUALTO, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -91,7 +88,6 @@ public: FieldValue fieldValue; QueryValueType type = GetFieldTypeAndValue(value, fieldValue); ExecuteCompareOperation(QueryObjType::LESS_THAN_OR_EQUALTO, field, type, fieldValue); - SetIsDeviceSyncQuery(true); return *this; } @@ -117,7 +113,6 @@ public: } ExecuteCompareOperation(QueryObjType::IN, field, type, fieldValues); - SetIsDeviceSyncQuery(true); return *this; } @@ -133,7 +128,6 @@ public: } ExecuteCompareOperation(QueryObjType::NOT_IN, field, type, fieldValues); - SetIsDeviceSyncQuery(true); return *this; } @@ -166,8 +160,6 @@ private: DB_SYMBOL void ExecuteCompareOperation(QueryObjType operType, const std::string &field, const QueryValueType type, const std::vector &fieldValue); - DB_SYMBOL void SetIsDeviceSyncQuery(bool isDeviceSync); - template QueryValueType GetFieldTypeAndValue(const T &queryValue, FieldValue &fieldValue) { diff --git a/kv_store/frameworks/libs/distributeddb/include/query_expression.h b/kv_store/frameworks/libs/distributeddb/include/query_expression.h index 8109cb5de097175da5c8d8b7728e5ac8006d1720..fffff65d1cd12d3903d97d3b654aa4a526b16a09 100644 --- a/kv_store/frameworks/libs/distributeddb/include/query_expression.h +++ b/kv_store/frameworks/libs/distributeddb/include/query_expression.h @@ -144,13 +144,19 @@ public: std::vector GetTables(); void SetTables(const std::vector &tableNames); - void SetIsDeviceSyncQuery(bool isDeviceSync = true); - bool GetIsDeviceSyncQuery() const; - + void From(const std::string &tableName); + int GetExpressionStatus() const; + std::vector GetQueryExpressions() const; private: void AssemblyQueryInfo(const QueryObjType queryOperType, const std::string &field, const QueryValueType type, const std::vector &value, bool isNeedFieldPath); + void SetNotSupportIfFromTables(); + + void SetNotSupportIfCondition(); + + void SetNotSupportIfNeed(QueryObjType type); + std::list queryInfo_; bool errFlag_ = true; std::vector prefixKey_; @@ -160,7 +166,12 @@ private: std::set keys_; int sortType_ = 0; std::vector tables_; - bool isWithDeviceSyncQuery_ = false; + + bool useFromTable_ = false; + std::string fromTable_; + std::list tableSequence_; + std::map expressions_; + int validStatus_ = 0; }; // specialize for double diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h index d62d4546f20330e76e91da600b66f5c1057f77d2..0e12b96554a42c98e5aa907f661bdfba4b9238d3 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h @@ -22,6 +22,7 @@ #include #include +#include "query.h" #include "store_types.h" namespace DistributedDB { @@ -89,5 +90,33 @@ struct DataBaseSchema { std::vector tables; }; +enum class CloudQueryType : int64_t { + FULL_TABLE = 0, // query full table + QUERY_FIELD = 1 // query with some fields +}; + +struct CloudSyncOption { + std::vector devices; + SyncMode mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + Query query; + int64_t waitTime = 0; + bool priorityTask = false; +}; + +enum class QueryNodeType : uint32_t { + ILLEGAL = 0, + IN = 1, + OR = 0x101, + AND, + EQUAL_TO = 0x201, + BEGIN_GROUP = 0x301, + END_GROUP +}; + +struct QueryNode { + QueryNodeType type = QueryNodeType::ILLEGAL; + std::string fieldName; + std::vector fieldValue; +}; } // namespace DistributedDB #endif // CLOUD_STORE_TYPE_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_client.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_client.h index 1a5459050bfbfdd937f3dbfed8afeba8c5575a69..f2a57d7fcfa9592cf1a6195c7bf3d36025d268e5 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_client.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_client.h @@ -19,13 +19,14 @@ #include #include #include +#include #include "sqlite3.h" #include "store_types.h" struct ClientChangedData { - std::string tableName; + std::set tableNames; }; using ClientObserver = std::function; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h index b0981f227ac42e2c9050ff0e5185d81e9a315a61..ee0b2687f28fd22d9c4f5a0032f827af1c7ad2bb 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h @@ -79,7 +79,11 @@ public: DB_API virtual DBStatus UnRegisterObserver() = 0; + DB_API virtual DBStatus UnRegisterObserver(StoreObserver *observer) = 0; + DB_API virtual DBStatus SetIAssetLoader(const std::shared_ptr &loader) = 0; + + DB_API virtual DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) = 0; protected: virtual DBStatus RemoveDeviceDataInner(const std::string &device, ClearMode mode) = 0; virtual DBStatus CreateDistributedTableInner(const std::string &tableName, TableSyncType type) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h index a7daf9b67e16bbe0dda8202d3f744bfea3ff80ad..0e31d33ba691e7de44529d58bb39ffd394ff634d 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h @@ -53,6 +53,8 @@ public: // deprecated DB_API static std::string GetRelationalStoreIdentifier(const std::string &userId, const std::string &appId, const std::string &storeId, bool syncDualTupleMode = false); + + DB_API static std::vector ParserQueryNodes(const Bytes &queryBytes, DBStatus &status); private: bool PreCheckOpenStore(const std::string &path, const std::string &storeId, RelationalStoreDelegate *&delegate, std::string &canonicalDir); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h index 2d8e5c5aa35121ddc38038d5c1e04ba613878d90..6b908cec5ee73c1a818e08a1e1cb28500b3498a9 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h @@ -35,7 +35,7 @@ enum ChangedDataType : uint32_t { struct ChangedData { std::string tableName; - ChangedDataType type; + ChangedDataType type = DATA; // CLOUD_COOPERATION mode, primaryData store primary keys // primaryData store row id if have no data std::vector> primaryData[OP_BUTT]; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp index 9854e2bf2e355c042788b162949794ce4addb713..1d68d61b07ab8c1d5d46f29c6cd6929e48b68c7f 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp @@ -343,7 +343,6 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor callback(OK, kvStore); } - DBStatus KvStoreDelegateManager::CloseKvStore(KvStoreDelegate *kvStore) { #ifndef OMIT_MULTI_VER @@ -540,7 +539,7 @@ DBStatus KvStoreDelegateManager::EnableKvStoreAutoLaunch(const std::string &user if (RuntimeContext::GetInstance() == nullptr) { return DB_ERROR; } - AutoLaunchParam param{ userId, appId, storeId, option, notifier, {}}; + AutoLaunchParam param{ userId, appId, storeId, option, notifier, {} }; std::shared_ptr ptr; int errCode = AutoLaunch::GetAutoLaunchProperties(param, DBTypeInner::DB_KV, true, ptr); if (errCode != E_OK) { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp index c6e2b14cd99364891e8eecba7b2d91b574686023..f40f259b1c62f5dc26beb7b71beb0d9757f1ad74 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp @@ -18,6 +18,7 @@ #include #include +#include "db_common.h" #include "db_constant.h" #include "db_errno.h" #include "db_types.h" @@ -386,7 +387,7 @@ DBStatus KvStoreNbDelegateImpl::RegisterObserver(const Key &key, unsigned int mo std::lock_guard lockGuard(observerMapLock_); if (observerMap_.find(observer) != observerMap_.end()) { LOGE("[KvStoreNbDelegate] Observer has been already registered!"); - return DB_ERROR; + return ALREADY_SET; } if (conn_ == nullptr) { @@ -504,6 +505,9 @@ DBStatus KvStoreNbDelegateImpl::Sync(const std::vector &devices, Sy return NOT_SUPPORT; } + if (!DBCommon::CheckQueryWithoutMultiTable(query)) { + return NOT_SUPPORT; + } QuerySyncObject querySyncObj(query); if (querySyncObj.GetSortType() != SortType::NONE) { LOGE("not support order by timestamp"); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index e1d132a57d6c99b5c36c3a14cc3f627a1eaa68c1..400049cb59621f2ceecf5425ea00d41f47e36b51 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -15,7 +15,6 @@ #ifdef RELATIONAL_STORE #include "relational_store_delegate_impl.h" -#include "cloud/cloud_db_constant.h" #include "db_common.h" #include "db_errno.h" #include "cloud/cloud_db_constant.h" @@ -115,6 +114,10 @@ DBStatus RelationalStoreDelegateImpl::Sync(const std::vector &devic return NOT_SUPPORT; } + if (!DBCommon::CheckQueryWithoutMultiTable(query)) { + LOGE("not support query with tables"); + return NOT_SUPPORT; + } RelationalStoreConnection::SyncInfo syncInfo{devices, mode, std::bind(&RelationalStoreDelegateImpl::OnSyncComplete, std::placeholders::_1, onComplete), query, wait}; int errCode = conn_->SyncToDevice(syncInfo); @@ -226,7 +229,12 @@ DBStatus RelationalStoreDelegateImpl::Sync(const std::vector &devic if (conn_ == nullptr) { return DB_ERROR; } - int errCode = conn_->Sync(devices, mode, query, onProcess, waitTime); + CloudSyncOption option; + option.devices = devices; + option.mode = mode; + option.query = query; + option.waitTime = waitTime; + int errCode = conn_->Sync(option, onProcess); if (errCode != E_OK) { LOGW("[RelationalStore Delegate] cloud sync failed:%d", errCode); return TransferDBErrno(errCode); @@ -252,6 +260,9 @@ DBStatus RelationalStoreDelegateImpl::SetCloudDbSchema(const DataBaseSchema &sch DBStatus RelationalStoreDelegateImpl::RegisterObserver(StoreObserver *observer) { + if (observer == nullptr) { + return INVALID_ARGS; + } if (conn_ == nullptr) { return DB_ERROR; } @@ -262,8 +273,8 @@ DBStatus RelationalStoreDelegateImpl::RegisterObserver(StoreObserver *observer) if (errCode != E_OK) { return DB_ERROR; } - conn_->RegisterObserverAction([observer, userId, appId, storeId](const std::string &changedDevice, - ChangedData &&changedData, bool isChangedData) { + errCode = conn_->RegisterObserverAction(observer, [observer, userId, appId, storeId]( + const std::string &changedDevice, ChangedData &&changedData, bool isChangedData) { if (isChangedData && observer != nullptr) { observer->OnChange(Origin::ORIGIN_CLOUD, changedDevice, std::move(changedData)); LOGD("begin to observer on changed data"); @@ -276,7 +287,7 @@ DBStatus RelationalStoreDelegateImpl::RegisterObserver(StoreObserver *observer) observer->OnChange(data); } }); - return OK; + return TransferDBErrno(errCode); } DBStatus RelationalStoreDelegateImpl::SetIAssetLoader(const std::shared_ptr &loader) @@ -289,7 +300,35 @@ DBStatus RelationalStoreDelegateImpl::SetIAssetLoader(const std::shared_ptrUnRegisterObserverAction(nullptr)); +} + +DBStatus RelationalStoreDelegateImpl::UnRegisterObserver(StoreObserver *observer) +{ + if (observer == nullptr) { + return INVALID_ARGS; + } + if (conn_ == nullptr) { + return DB_ERROR; + } + return TransferDBErrno(conn_->UnRegisterObserverAction(observer)); +} + +DBStatus RelationalStoreDelegateImpl::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) +{ + if (conn_ == nullptr) { + return DB_ERROR; + } + int errCode = conn_->Sync(option, onProcess); + if (errCode != E_OK) { + LOGE("[RelationalStore Delegate] cloud sync failed:%d", errCode); + return TransferDBErrno(errCode); + } + return OK; } } // namespace DistributedDB #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h index 45c8906b5262091e316f6705c67074b2d585c671..5028d9366a79d4019209aeb99721fa0bb5d3fab1 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h @@ -61,7 +61,11 @@ public: DBStatus UnRegisterObserver() override; + DBStatus UnRegisterObserver(StoreObserver *observer) override; + DBStatus SetIAssetLoader(const std::shared_ptr &loader) override; + + DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) override; private: static void OnSyncComplete(const std::map> &devicesStatus, const SyncStatusCallback &onComplete); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index ef3f600d16ff777e59ee9347072d2e68921ae5f3..b3886e8709f2cadf7e5cf058fc2f8aa2eeb78094 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -18,18 +18,19 @@ #include #include "auto_launch.h" -#include "cloud/cloud_db_constant.h" -#include "cloud/cloud_storage_utils.h" -#include "relational_store_instance.h" #include "db_common.h" #include "db_dfx_adapter.h" #include "db_errno.h" +#include "cloud/cloud_db_constant.h" +#include "cloud/cloud_storage_utils.h" #include "kv_store_errno.h" #include "log_print.h" #include "param_check_utils.h" #include "platform_specific.h" +#include "query_sync_object.h" #include "relational_store_changed_data_impl.h" #include "relational_store_delegate_impl.h" +#include "relational_store_instance.h" #include "runtime_config.h" #include "runtime_context.h" @@ -147,7 +148,7 @@ DB_API std::string RelationalStoreManager::GetDistributedLogTableName(const std: return DBCommon::GetLogTableName(tableName); } -int static GetCollateTypeByName(const std::map &collateTypeMap, +static int GetCollateTypeByName(const std::map &collateTypeMap, const std::string &name, CollateType &collateType) { auto it = collateTypeMap.find(name); @@ -224,5 +225,13 @@ std::string RelationalStoreManager::GetRelationalStoreIdentifier(const std::stri { return RuntimeConfig::GetStoreIdentifier(userId, appId, storeId, syncDualTupleMode); } + +std::vector RelationalStoreManager::ParserQueryNodes(const Bytes &queryBytes, + DBStatus &status) +{ + std::vector res; + status = TransferDBErrno(QuerySyncObject::ParserQueryNodes(queryBytes, res)); + return res; +} } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index 5bf899b65d30bd161c58393e19793db088b07ca9..e024055aa69146e2001d0fc1ec17b9ff8e1a819f 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -19,7 +19,10 @@ #include #include +#include "db_common.h" +#include "platform_specific.h" #include "relational_store_client.h" +#include "runtime_context.h" // using the "sqlite3sym.h" in OHOS #ifndef USE_SQLITE_SYMBOLS @@ -28,9 +31,30 @@ #include "sqlite3sym.h" #endif +#if defined _WIN32 +#ifndef RUNNING_ON_WIN +#define RUNNING_ON_WIN +#endif +#else +#ifndef RUNNING_ON_LINUX +#define RUNNING_ON_LINUX +#endif +#endif + +#if defined(RUNNING_ON_LINUX) +#include +#elif defined RUNNING_ON_WIN +#include +#else +#error "PLATFORM NOT SPECIFIED!" +#endif + +using namespace DistributedDB; + namespace { constexpr int E_OK = 0; constexpr int E_ERROR = 1; +constexpr int STR_TO_LL_BY_DEVALUE = 10; constexpr int BUSY_TIMEOUT = 2000; // 2s. const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit const std::string DEVICE_TYPE = "device"; @@ -89,43 +113,24 @@ private: SHA256_CTX *context_ = nullptr; }; -const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000; - using Timestamp = uint64_t; using TimeOffset = int64_t; class TimeHelper { public: - constexpr static int64_t BASE_OFFSET = 10000LL * 365LL * 24LL * 3600LL * 1000LL * 1000LL * 10L; // 10000 year 100ns + // 10000 year 100ns + static constexpr int64_t BASE_OFFSET = 10000LL * 365LL * 24LL * 3600LL * 1000LL * 1000LL * 10L; - constexpr static int64_t MAX_VALID_TIME = BASE_OFFSET * 2; // 20000 year 100ns + static constexpr int64_t MAX_VALID_TIME = BASE_OFFSET * 2; // 20000 year 100ns - constexpr static uint64_t TO_100_NS = 10; // 1us to 100ns + static constexpr uint64_t TO_100_NS = 10; // 1us to 100ns - constexpr static Timestamp INVALID_TIMESTAMP = 0; + static constexpr Timestamp INVALID_TIMESTAMP = 0; - // Get current system time - static Timestamp GetSysCurrentTime() - { - uint64_t curTime = 0; - int errCode = GetCurrentSysTimeInMicrosecond(curTime); - if (errCode != E_OK) { - return INVALID_TIMESTAMP; - } + static constexpr uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000; - std::lock_guard lock(systemTimeLock_); - // If GetSysCurrentTime in 1us, we need increase the currentIncCount_ - if (curTime == lastSystemTimeUs_) { - // if the currentIncCount_ has been increased MAX_INC_COUNT, keep the currentIncCount_ - if (currentIncCount_ < MAX_INC_COUNT) { - currentIncCount_++; - } - } else { - lastSystemTimeUs_ = curTime; - currentIncCount_ = 0; - } - return (curTime * TO_100_NS) + currentIncCount_; // Currently Timestamp is uint64_t - } + static constexpr int64_t MAX_NOISE = 9 * 100 * 1000; // 900ms + static constexpr uint64_t MAX_INC_COUNT = 9; // last bit from 0-9 static int GetSysCurrentRawTime(uint64_t &curTime) { @@ -137,30 +142,116 @@ public: return E_OK; } - // Init the TimeHelper - static void Initialize(Timestamp maxTimestamp) + // Init the TimeHelper for time skew + void Initialize() { - std::lock_guard lock(lastLocalTimeLock_); - if (lastLocalTime_ < maxTimestamp) { - lastLocalTime_ = maxTimestamp; + // it maybe a rebuild db when initialize with localTimeOffset is TimeHelper::BASE_OFFSET + // reinitialize for this db + if (isInitialized_) { + return; } + (void)GetCurrentSysTimeInMicrosecond(lastSystemTime_); + (void)OS::GetMonotonicRelativeTimeInMicrosecond(lastMonotonicTime_); + LOGD("Initialize time helper skew: %" PRIu64 " %" PRIu64, lastSystemTime_, lastMonotonicTime_); + isInitialized_ = true; } - static Timestamp GetTime(TimeOffset timeOffset) + Timestamp GetTime(TimeOffset timeOffset, const std::function &getDbMaxTimestamp, + const std::function &getDbLocalTimeOffset) { + if (!isLoaded_) { // First use, load max time stamp and local time offset from db; + if (getDbMaxTimestamp != nullptr) { + lastLocalTime_ = getDbMaxTimestamp(); + } + if (getDbLocalTimeOffset != nullptr) { + localTimeOffset_ = getDbLocalTimeOffset(); + } + LOGD("First use time helper with maxTimestamp:%" PRIu64 " localTimeOffset:%" PRIu64, lastLocalTime_, + localTimeOffset_); + isLoaded_ = true; + } + Timestamp currentSystemTime; + (void)GetCurrentSysTimeInMicrosecond(currentSystemTime); + Timestamp currentMonotonicTime; + (void)OS::GetMonotonicRelativeTimeInMicrosecond(currentMonotonicTime); + auto deltaTime = static_cast(currentMonotonicTime - lastMonotonicTime_); Timestamp currentSysTime = GetSysCurrentTime(); - Timestamp currentLocalTime = currentSysTime + timeOffset; - std::lock_guard lock(lastLocalTimeLock_); + Timestamp currentLocalTime = currentSysTime + timeOffset + localTimeOffset_; if (currentLocalTime <= lastLocalTime_ || currentLocalTime > MAX_VALID_TIME) { - lastLocalTime_++; + LOGD("Ext invalid time: lastLocalTime_: %" PRIu64 ", currentLocalTime: %" PRIu64 ", deltaTime: %" PRId64, + lastLocalTime_, currentLocalTime, deltaTime); + lastLocalTime_ = static_cast(static_cast(lastLocalTime_) + + deltaTime * static_cast(TO_100_NS)); currentLocalTime = lastLocalTime_; } else { lastLocalTime_ = currentLocalTime; } + + lastSystemTime_ = currentSystemTime; + lastMonotonicTime_ = currentMonotonicTime; return currentLocalTime; } -private: + bool TimeSkew(const std::function &getLocalTimeOffsetFromDB, Timestamp timeOffset) + { + Timestamp currentSystemTime; + (void)GetCurrentSysTimeInMicrosecond(currentSystemTime); + Timestamp currentMonotonicTime; + (void)OS::GetMonotonicRelativeTimeInMicrosecond(currentMonotonicTime); + + auto systemTimeOffset = static_cast(currentSystemTime - lastSystemTime_); + auto monotonicTimeOffset = static_cast(currentMonotonicTime - lastMonotonicTime_); + if (std::abs(systemTimeOffset - monotonicTimeOffset) > MAX_NOISE) { + // time skew detected + Timestamp localTimeOffset = getLocalTimeOffsetFromDB(); + Timestamp currentSysTime = GetSysCurrentTime(); + Timestamp currentLocalTime = currentSysTime + timeOffset + localTimeOffset; + auto virtualTimeOffset = static_cast(currentLocalTime - lastLocalTime_); + auto changedOffset = static_cast(virtualTimeOffset - monotonicTimeOffset * TO_100_NS); + if (std::abs(changedOffset) > static_cast(MAX_NOISE * TO_100_NS)) { + // localTimeOffset was not flushed, use temporary calculated value + localTimeOffset_ = static_cast(static_cast(localTimeOffset_) - + (systemTimeOffset - monotonicTimeOffset) * static_cast(TO_100_NS)); + LOGD("Save ext local time offset: %" PRIu64 ", changedOffset: %" PRId64, localTimeOffset_, + changedOffset); + } else { + localTimeOffset_ = localTimeOffset; + LOGD("Save ext local time offset: %" PRIu64, localTimeOffset_); + } + } + lastSystemTime_ = currentSystemTime; + lastMonotonicTime_ = currentMonotonicTime; + return std::abs(systemTimeOffset - monotonicTimeOffset) > MAX_NOISE; + } + + Timestamp GetLastTime() const + { + return lastLocalTime_; + } + + // Get current system time + static Timestamp GetSysCurrentTime() + { + uint64_t curTime = 0; + int errCode = GetCurrentSysTimeInMicrosecond(curTime); + if (errCode != E_OK) { + return INVALID_TIMESTAMP; + } + + std::lock_guard lock(systemTimeLock_); + // If GetSysCurrentTime in 1us, we need increase the currentIncCount_ + if (curTime == lastSystemTimeUs_) { + // if the currentIncCount_ has been increased MAX_INC_COUNT, keep the currentIncCount_ + if (currentIncCount_ < MAX_INC_COUNT) { + currentIncCount_++; + } + } else { + lastSystemTimeUs_ = curTime; + currentIncCount_ = 0; + } + return (curTime * TO_100_NS) + currentIncCount_; // Currently Timestamp is uint64_t + } + static int GetCurrentSysTimeInMicrosecond(uint64_t &outTime) { struct timeval rawTime; @@ -176,17 +267,92 @@ private: static std::mutex systemTimeLock_; static Timestamp lastSystemTimeUs_; static Timestamp currentIncCount_; - static const uint64_t MAX_INC_COUNT = 9; // last bit from 0-9 - static Timestamp lastLocalTime_; - static std::mutex lastLocalTimeLock_; + Timestamp lastLocalTime_ = 0; + Timestamp localTimeOffset_ = TimeHelper::BASE_OFFSET; + bool isLoaded_ = false; + + Timestamp lastSystemTime_ = 0; + Timestamp lastMonotonicTime_ = 0; + bool isInitialized_ = false; +}; + +class TimeHelperManager { +public: + static TimeHelperManager *GetInstance() + { + static auto instance = new TimeHelperManager(); + return instance; + } + + void AddStore(const std::string &storeId) + { + std::lock_guard lock(metaDataLock_); + if (metaData_.find(storeId) != metaData_.end()) { + return; + } + TimeHelper timeHelper; + timeHelper.Initialize(); + metaData_[storeId] = timeHelper; + } + + void Restore(const std::string &storeId) + { + std::lock_guard lock(metaDataLock_); + if (metaData_.find(storeId) != metaData_.end()) { + LOGD("Restore time helper"); + metaData_.erase(storeId); + } + } + + Timestamp GetLastTime(const std::string &storeId) + { + std::lock_guard lock(metaDataLock_); + auto it = metaData_.find(storeId); + if (it == metaData_.end()) { + return TimeHelper::INVALID_TIMESTAMP; + } + return it->second.GetLastTime(); + } + + bool TimeSkew(const std::string &storeId, const std::function &getLocalTimeOffsetFromDB, + Timestamp timeOffset) + { + std::lock_guard lock(metaDataLock_); + auto it = metaData_.find(storeId); + if (it == metaData_.end()) { + return false; + } + return it->second.TimeSkew(getLocalTimeOffsetFromDB, timeOffset); + } + + Timestamp GetTime(const std::string &storeId, TimeOffset timeOffset, + const std::function &getDbMaxTimestamp, const std::function &getDbLocalTimeOffset) + { + std::lock_guard lock(metaDataLock_); + auto it = metaData_.find(storeId); + if (it == metaData_.end()) { + return TimeHelper::INVALID_TIMESTAMP; + } + return it->second.GetTime(timeOffset, getDbMaxTimestamp, getDbLocalTimeOffset); + } +private: + TimeHelperManager() = default; + std::mutex metaDataLock_; + std::map metaData_; }; std::mutex TimeHelper::systemTimeLock_; Timestamp TimeHelper::lastSystemTimeUs_ = 0; Timestamp TimeHelper::currentIncCount_ = 0; -Timestamp TimeHelper::lastLocalTime_ = 0; -std::mutex TimeHelper::lastLocalTimeLock_; + +int GetStatement(sqlite3 *db, const std::string &sql, sqlite3_stmt *&stmt); +int ResetStatement(sqlite3_stmt *&stmt); +int BindBlobToStatement(sqlite3_stmt *stmt, int index, const std::vector &value, bool permEmpty = false); +int StepWithRetry(sqlite3_stmt *stmt); +int GetColumnBlobValue(sqlite3_stmt *stmt, int index, std::vector &value); +int GetColumnTextValue(sqlite3_stmt *stmt, int index, std::string &value); +int GetDBIdentity(sqlite3 *db, std::string &identity); struct TransactFunc { void (*xFunc)(sqlite3_context*, int, sqlite3_value**) = nullptr; @@ -197,18 +363,8 @@ struct TransactFunc { std::mutex g_clientObserverMutex; std::map g_clientObserverMap; - -void StringToVector(const std::string &src, std::vector &dst) -{ - dst.resize(src.size()); - dst.assign(src.begin(), src.end()); -} - -void VectorToString(const std::vector &src, std::string &dst) -{ - dst.clear(); - dst.assign(src.begin(), src.end()); -} +std::mutex g_clientChangedDataMutex; +std::map g_clientChangedDataMap; int RegisterFunction(sqlite3 *db, const std::string &funcName, int nArg, void *uData, TransactFunc &func) { @@ -247,14 +403,6 @@ void StringToUpper(std::string &str) }); } -void RTrim(std::string &str) -{ - if (str.empty()) { - return; - } - str.erase(str.find_last_not_of(" ") + 1); -} - void CalcHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv) { // 1 means that the function only needs one parameter, namely key @@ -273,7 +421,7 @@ void CalcHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv) std::string colStr(colChar); StringToUpper(colStr); std::vector value; - StringToVector(colStr, value); + value.assign(colStr.begin(), colStr.end()); errCode = CalcValueHash(value, hashValue); } else if (collateType == DistributedDB::CollateType::COLLATE_RTRIM) { auto colChar = reinterpret_cast(sqlite3_value_text(argv[0])); @@ -281,9 +429,9 @@ void CalcHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv) return; } std::string colStr(colChar); - RTrim(colStr); + DBCommon::RTrim(colStr); std::vector value; - StringToVector(colStr, value); + value.assign(colStr.begin(), colStr.end()); errCode = CalcValueHash(value, hashValue); } else { auto keyBlob = static_cast(sqlite3_value_blob(argv[0])); @@ -302,7 +450,6 @@ void CalcHashKey(sqlite3_context *ctx, int argc, sqlite3_value **argv) return; } sqlite3_result_blob(ctx, hashValue.data(), hashValue.size(), SQLITE_TRANSIENT); - return; } int RegisterCalcHash(sqlite3 *db) @@ -312,13 +459,84 @@ int RegisterCalcHash(sqlite3 *db) return RegisterFunction(db, "calc_hash", 2, nullptr, func); // 2 is params count } +int GetLocalTimeOffsetFromMeta(sqlite3 *db, TimeOffset &offset) +{ + if (db == nullptr) { + return -E_ERROR; + } + + sqlite3_stmt *stmt = nullptr; + int errCode = GetStatement(db, "SELECT value FROM naturalbase_rdb_aux_metadata WHERE key = ?", stmt); + if (errCode != E_OK) { + LOGE("Prepare mate data stmt failed. %d", errCode); + return -E_ERROR; + } + + std::string keyStr = "localTimeOffset"; + std::vector key(keyStr.begin(), keyStr.end()); + errCode = BindBlobToStatement(stmt, 1, key); + if (errCode != E_OK) { + (void)ResetStatement(stmt); + LOGE("Bind meta data stmt failed, Key: %s. %d", keyStr.c_str(), errCode); + return -E_ERROR; + } + + std::vector value; + errCode = StepWithRetry(stmt); + if (errCode == SQLITE_ROW) { + GetColumnBlobValue(stmt, 0, value); + } else if (errCode == SQLITE_DONE) { + (void)ResetStatement(stmt); + LOGE("Get meta data not found, Key: %s. %d", keyStr.c_str(), errCode); + return E_OK; + } else { + (void)ResetStatement(stmt); + LOGE("Get meta data failed, Key: %s. %d", keyStr.c_str(), errCode); + return -E_ERROR; + } + + std::string valueStr(value.begin(), value.end()); + int64_t result = std::strtoll(valueStr.c_str(), nullptr, STR_TO_LL_BY_DEVALUE); + if (errno != ERANGE && result != LLONG_MIN && result != LLONG_MAX) { + offset = result; + } + (void)ResetStatement(stmt); + LOGD("Get local time offset from meta: %" PRId64, offset); + return E_OK; +} + +int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp); + void GetSysTime(sqlite3_context *ctx, int argc, sqlite3_value **argv) { if (ctx == nullptr || argc != 1 || argv == nullptr) { // 1: function need one parameter return; } - int timeOffset = static_cast(sqlite3_value_int64(argv[0])); - sqlite3_result_int64(ctx, (sqlite3_int64)TimeHelper::GetTime(timeOffset)); + + auto *db = static_cast(sqlite3_user_data(ctx)); + if (db == nullptr) { + sqlite3_result_error(ctx, "Sqlite context is invalid.", -1); + return; + } + + std::function getDbMaxTimestamp = [db]() -> Timestamp { + Timestamp maxTimestamp = 0; + (void)GetCurrentMaxTimestamp(db, maxTimestamp); + return maxTimestamp; + }; + std::function getDbLocalTimeOffset = [db]() -> Timestamp { + TimeOffset localTimeOffset = TimeHelper::BASE_OFFSET; + (void)GetLocalTimeOffsetFromMeta(db, localTimeOffset); + return localTimeOffset; + }; + + std::string identity; + GetDBIdentity(db, identity); + auto timeOffset = static_cast(sqlite3_value_int64(argv[0])); + (void)TimeHelperManager::GetInstance()->TimeSkew(identity, getDbLocalTimeOffset, timeOffset); + Timestamp currentTime = TimeHelperManager::GetInstance()->GetTime(identity, timeOffset, getDbMaxTimestamp, + getDbLocalTimeOffset); + sqlite3_result_int64(ctx, (sqlite3_int64)currentTime); } void GetRawSysTime(sqlite3_context *ctx, int argc, sqlite3_value **argv) @@ -342,19 +560,28 @@ void GetLastTime(sqlite3_context *ctx, int argc, sqlite3_value **argv) return; } - sqlite3_result_int64(ctx, (sqlite3_int64)TimeHelper::GetTime(0)); + auto *db = static_cast(sqlite3_user_data(ctx)); + if (db == nullptr) { + sqlite3_result_error(ctx, "Sqlite context is invalid.", -1); + return; + } + std::string identity; + GetDBIdentity(db, identity); + + sqlite3_result_int64(ctx, (sqlite3_int64)TimeHelperManager::GetInstance()->GetLastTime(identity)); } int GetHashString(const std::string &str, std::string &dst) { std::vector strVec; - StringToVector(str, strVec); + strVec.assign(str.begin(), str.end()); std::vector hashVec; int errCode = CalcValueHash(strVec, hashVec); if (errCode != E_OK) { + LOGE("calc hash value fail, %d", errCode); return errCode; } - VectorToString(hashVec, dst); + dst.assign(hashVec.begin(), hashVec.end()); return E_OK; } @@ -382,55 +609,117 @@ void CloudDataChangedObserver(sqlite3_context *ctx, int argc, sqlite3_value **ar if (!GetDbFileName(db, fileName)) { return; } - std::string hashFileName; int errCode = GetHashString(fileName, hashFileName); if (errCode != DistributedDB::DBStatus::OK) { return; } - std::lock_guard lock(g_clientObserverMutex); - auto it = g_clientObserverMap.find(hashFileName); - if (it != g_clientObserverMap.end()) { - auto tableNameChar = reinterpret_cast(sqlite3_value_text(argv[0])); - if (tableNameChar == nullptr) { - return; + auto tableNameChar = reinterpret_cast(sqlite3_value_text(argv[0])); + if (tableNameChar == nullptr) { + return; + } + std::string tableName = static_cast(tableNameChar); + bool isExistObserver = false; + { + std::lock_guard lock(g_clientObserverMutex); + auto it = g_clientObserverMap.find(hashFileName); + isExistObserver = (it != g_clientObserverMap.end()); + } + { + std::lock_guard lock(g_clientChangedDataMutex); + if (isExistObserver) { + g_clientChangedDataMap[hashFileName].tableNames.insert(tableName); } + } + sqlite3_result_int64(ctx, static_cast(1)); +} - if (it->second != nullptr) { - std::string tableName = std::string(tableNameChar); - ClientChangedData clientChangedData { tableName }; - it->second(clientChangedData); +int CommitHookCallback(void *data) +{ + sqlite3 *db = static_cast(data); + std::string fileName; + if (!GetDbFileName(db, fileName)) { + return 0; + } + std::string hashFileName; + int errCode = GetHashString(fileName, hashFileName); + if (errCode != DistributedDB::DBStatus::OK) { + return 0; + } + ClientObserver clientObserver; + { + std::lock_guard clientObserverLock(g_clientObserverMutex); + auto it = g_clientObserverMap.find(hashFileName); + if (it != g_clientObserverMap.end() && it->second != nullptr) { + clientObserver = it->second; + } else { + return 0; } } - sqlite3_result_int64(ctx, (sqlite3_int64)1); + std::lock_guard clientChangedDataLock(g_clientChangedDataMutex); + auto it = g_clientChangedDataMap.find(hashFileName); + if (it != g_clientChangedDataMap.end() && !it->second.tableNames.empty()) { + ClientChangedData clientChangedData = g_clientChangedDataMap[hashFileName]; + errCode = DistributedDB::RuntimeContext::GetInstance()->ScheduleTask([clientObserver, clientChangedData] { + ClientChangedData taskClientChangedData = clientChangedData; + clientObserver(taskClientChangedData); + }); + g_clientChangedDataMap[hashFileName].tableNames.clear(); + } + return 0; +} + +void RollbackHookCallback(void* data) +{ + sqlite3 *db = static_cast(data); + std::string fileName; + if (!GetDbFileName(db, fileName)) { + return; + } + std::string hashFileName; + int errCode = GetHashString(fileName, hashFileName); + if (errCode != DistributedDB::DBStatus::OK) { + return; + } + std::lock_guard clientChangedDataLock(g_clientChangedDataMutex); + auto it = g_clientChangedDataMap.find(hashFileName); + if (it != g_clientChangedDataMap.end() && !it->second.tableNames.empty()) { + g_clientChangedDataMap[hashFileName].tableNames.clear(); + } } int RegisterGetSysTime(sqlite3 *db) { TransactFunc func; func.xFunc = &GetSysTime; - return RegisterFunction(db, "get_sys_time", 1, nullptr, func); + return RegisterFunction(db, "get_sys_time", 1, db, func); } -int RegisterGetRawSysTime(sqlite3 *db) +int RegisterGetLastTime(sqlite3 *db) { TransactFunc func; - func.xFunc = &GetRawSysTime; - return RegisterFunction(db, "get_raw_sys_time", 0, nullptr, func); + func.xFunc = &GetLastTime; + return RegisterFunction(db, "get_last_time", 0, db, func); } -int RegisterGetLastTime(sqlite3 *db) +int RegisterGetRawSysTime(sqlite3 *db) { TransactFunc func; - func.xFunc = &GetLastTime; - return RegisterFunction(db, "get_last_time", 0, nullptr, func); + func.xFunc = &GetRawSysTime; + return RegisterFunction(db, "get_raw_sys_time", 0, nullptr, func); } int RegisterCloudDataChangeObserver(sqlite3 *db) { TransactFunc func; func.xFunc = &CloudDataChangedObserver; - return RegisterFunction(db, "client_observer", 3, db, func); // 3 is param counts const_cast(dbFilePath) + return RegisterFunction(db, "client_observer", 3, db, func); // 3 is param counts +} + +void RegisterCommitAndRollbackHook(sqlite3 *db) +{ + sqlite3_commit_hook(db, CommitHookCallback, db); + sqlite3_rollback_hook(db, RollbackHookCallback, db); } int ResetStatement(sqlite3_stmt *&stmt) @@ -447,6 +736,7 @@ int GetStatement(sqlite3 *db, const std::string &sql, sqlite3_stmt *&stmt) int errCode = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr); if (errCode != SQLITE_OK) { (void)ResetStatement(stmt); + LOGE("Get stmt failed. %d", errCode); return -E_ERROR; } return E_OK; @@ -482,7 +772,22 @@ int StepWithRetry(sqlite3_stmt *stmt) return errCode; } -int GetColumnTestValue(sqlite3_stmt *stmt, int index, std::string &value) +int BindBlobToStatement(sqlite3_stmt *stmt, int index, const std::vector &value, bool permEmpty) +{ + if (stmt == nullptr || (value.empty() && !permEmpty)) { + return -E_ERROR; + } + int errCode; + if (value.empty()) { + errCode = sqlite3_bind_zeroblob(stmt, index, -1); // -1: zero-length blob + } else { + errCode = sqlite3_bind_blob(stmt, index, static_cast(value.data()), value.size(), + SQLITE_TRANSIENT); + } + return errCode == E_OK ? E_OK : -E_ERROR; +} + +int GetColumnTextValue(sqlite3_stmt *stmt, int index, std::string &value) { if (stmt == nullptr) { return -E_ERROR; @@ -492,6 +797,30 @@ int GetColumnTestValue(sqlite3_stmt *stmt, int index, std::string &value) return E_OK; } +int GetColumnBlobValue(sqlite3_stmt *stmt, int index, std::vector &value) +{ + if (stmt == nullptr) { + return -E_ERROR; + } + + int keySize = sqlite3_column_bytes(stmt, index); + if (keySize < 0) { + value.resize(0); + return E_OK; + } + auto keyRead = static_cast(sqlite3_column_blob(stmt, index)); + if (keySize == 0 || keyRead == nullptr) { + value.resize(0); + } else { + if (keySize > MAX_BLOB_READ_SIZE) { + keySize = MAX_BLOB_READ_SIZE + 1; + } + value.resize(keySize); + value.assign(keyRead, keyRead + keySize); + } + return E_OK; +} + int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) { if (db == nullptr) { @@ -502,6 +831,7 @@ int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) sqlite3_stmt *checkTableStmt = nullptr; int errCode = GetStatement(db, checkTableSql, checkTableStmt); if (errCode != E_OK) { + LOGE("Prepare get max log timestamp statement failed. err=%d", errCode); return -E_ERROR; } while ((errCode = StepWithRetry(checkTableStmt)) != SQLITE_DONE) { @@ -510,7 +840,7 @@ int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) return -E_ERROR; } std::string logTablename; - GetColumnTestValue(checkTableStmt, 0, logTablename); + GetColumnTextValue(checkTableStmt, 0, logTablename); if (logTablename.empty()) { continue; } @@ -534,28 +864,22 @@ int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) return E_OK; } -int GetColumnBlobValue(sqlite3_stmt *stmt, int index, std::vector &value) +bool CheckTableExists(sqlite3 *db, const std::string &tableName) { - if (stmt == nullptr) { - return -E_ERROR; + sqlite3_stmt *stmt = nullptr; + std::string sql = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + tableName + "';"; + if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { + (void)sqlite3_finalize(stmt); + return false; } - int keySize = sqlite3_column_bytes(stmt, index); - if (keySize < 0) { - value.resize(0); - return E_OK; - } - auto keyRead = static_cast(sqlite3_column_blob(stmt, index)); - if (keySize == 0 || keyRead == nullptr) { - value.resize(0); - } else { - if (keySize > MAX_BLOB_READ_SIZE) { - keySize = MAX_BLOB_READ_SIZE + 1; - } - value.resize(keySize); - value.assign(keyRead, keyRead + keySize); + bool isLogTblExists = false; + if (sqlite3_step(stmt) == SQLITE_ROW && static_cast(sqlite3_column_int(stmt, 0))) { + isLogTblExists = true; } - return E_OK; + (void)sqlite3_finalize(stmt); + stmt = nullptr; + return isLogTblExists; } int GetTableSyncType(sqlite3 *db, const std::string &tableName, std::string &tableType) @@ -601,7 +925,7 @@ void HandleDropCloudSyncTable(sqlite3 *db, const std::string &tableName) (void)sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); std::string keyStr = SYNC_TABLE_TYPE + tableName; std::vector key(keyStr.begin(), keyStr.end()); - sql = "delete from naturalbase_rdb_aux_metadata where key = ?;"; + sql = "DELETE FROM naturalbase_rdb_aux_metadata WHERE key = ?;"; sqlite3_stmt *statement = nullptr; int errCode = sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr); if (errCode != SQLITE_OK) { @@ -611,35 +935,69 @@ void HandleDropCloudSyncTable(sqlite3 *db, const std::string &tableName) if (sqlite3_bind_blob(statement, 1, static_cast(key.data()), key.size(), SQLITE_TRANSIENT) != SQLITE_OK) { + (void)sqlite3_finalize(statement); return; } (void)sqlite3_step(statement); (void)sqlite3_finalize(statement); } +int SaveDeleteFlagToDB(sqlite3 *db, const std::string &tableName) +{ + std::string keyStr = DBConstant::TABLE_IS_DROPPED + tableName; + Key key; + DBCommon::StringToVector(keyStr, key); + Value value; + DBCommon::StringToVector("1", value); // 1 means delete + std::string sql = "insert or replace into naturalbase_rdb_aux_metadata values(?, ?);"; + sqlite3_stmt *statement = nullptr; + int errCode = sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr); + if (errCode != SQLITE_OK) { + LOGE("[SaveDeleteFlagToDB] prepare statement failed, %d", errCode); + (void)ResetStatement(statement); + return -E_ERROR; + } + + if (sqlite3_bind_blob(statement, 1, static_cast(key.data()), key.size(), + SQLITE_TRANSIENT) != SQLITE_OK) { + (void)sqlite3_finalize(statement); + LOGE("[SaveDeleteFlagToDB] bind key failed, %d", errCode); + return -E_ERROR; + } + if (sqlite3_bind_blob(statement, 2, static_cast(value.data()), value.size(), // 2 is column index + SQLITE_TRANSIENT) != SQLITE_OK) { + (void)sqlite3_finalize(statement); + LOGE("[SaveDeleteFlagToDB] bind value failed, %d", errCode); + return -E_ERROR; + } + errCode = sqlite3_step(statement); + if (errCode != SQLITE_DONE) { + LOGE("[SaveDeleteFlagToDB] step failed, %d", errCode); + (void)sqlite3_finalize(statement); + return -E_ERROR; + } + (void)sqlite3_finalize(statement); + return E_OK; +} + void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *schemaName) { if (db == nullptr || tableName == nullptr || schemaName == nullptr) { return; } - sqlite3_stmt *stmt = nullptr; - std::string tableStr = std::string(tableName); - std::string logTblName = "naturalbase_rdb_aux_" + tableStr + "_log"; - Timestamp dropTimeStamp = TimeHelper::GetTime(0); - std::string sql = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + logTblName + "';"; - if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { - (void)sqlite3_finalize(stmt); + auto filePath = sqlite3_db_filename(db, schemaName); + if (filePath == nullptr) { return; } - - bool isLogTblExists = false; - if (sqlite3_step(stmt) == SQLITE_ROW && static_cast(sqlite3_column_int(stmt, 0))) { - isLogTblExists = true; - } - (void)sqlite3_finalize(stmt); - stmt = nullptr; - - if (isLogTblExists) { + std::string fileName = std::string(filePath); + Timestamp dropTimeStamp = TimeHelperManager::GetInstance()->GetTime(fileName, 0, nullptr, nullptr); + std::string tableStr = std::string(tableName); + std::string logTblName = DBCommon::GetLogTableName(tableStr); + if (CheckTableExists(db, logTblName)) { + if (SaveDeleteFlagToDB(db, tableStr) != E_OK) { + // the failure of this step does not affect the following step, so we just write log + LOGW("[ClearTheLogAfterDropTable] save delete flag failed."); + } std::string tableType = DEVICE_TYPE; if (GetTableSyncType(db, tableStr, tableType) != DistributedDB::DBStatus::OK) { return; @@ -647,7 +1005,7 @@ void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *s if (tableType == DEVICE_TYPE) { RegisterGetSysTime(db); RegisterGetLastTime(db); - sql = "UPDATE " + logTblName + " SET flag=0x03, timestamp=get_sys_time(0) " + std::string sql = "UPDATE " + logTblName + " SET flag=0x03, timestamp=get_sys_time(0) " "WHERE flag&0x03=0x02 AND timestamp<" + std::to_string(dropTimeStamp); (void)sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); } else { @@ -656,16 +1014,30 @@ void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *s } } -void PostHandle(sqlite3 *db) +int GetDBIdentity(sqlite3 *db, std::string &identity) { - Timestamp currentMaxTimestamp = 0; - (void)GetCurrentMaxTimestamp(db, currentMaxTimestamp); - TimeHelper::Initialize(currentMaxTimestamp); + auto filePath = sqlite3_db_filename(db, "main"); + if (filePath == nullptr) { + return -E_ERROR; + } + identity = std::string(filePath); + return E_OK; +} + +void PostHandle(bool isExists, sqlite3 *db) +{ + std::string dbIdentity; + (void)GetDBIdentity(db, dbIdentity); + if (!isExists) { // first create db, clean old time helper + TimeHelperManager::GetInstance()->Restore(dbIdentity); + } + TimeHelperManager::GetInstance()->AddStore(dbIdentity); RegisterCalcHash(db); RegisterGetSysTime(db); RegisterGetLastTime(db); RegisterGetRawSysTime(db); RegisterCloudDataChangeObserver(db); + RegisterCommitAndRollbackHook(db); (void)sqlite3_set_droptable_handle(db, &ClearTheLogAfterDropTable); (void)sqlite3_busy_timeout(db, BUSY_TIMEOUT); std::string recursiveTrigger = "PRAGMA recursive_triggers = ON;"; @@ -675,31 +1047,34 @@ void PostHandle(sqlite3 *db) SQLITE_API int sqlite3_open_relational(const char *filename, sqlite3 **ppDb) { + bool isExists = (access(filename, 0) == 0); int err = sqlite3_open(filename, ppDb); if (err != SQLITE_OK) { return err; } - PostHandle(*ppDb); + PostHandle(isExists, *ppDb); return err; } SQLITE_API int sqlite3_open16_relational(const void *filename, sqlite3 **ppDb) { + bool isExists = (access(static_cast(filename), 0) == 0); int err = sqlite3_open16(filename, ppDb); if (err != SQLITE_OK) { return err; } - PostHandle(*ppDb); + PostHandle(isExists, *ppDb); return err; } SQLITE_API int sqlite3_open_v2_relational(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs) { + bool isExists = (access(filename, 0) == 0); int err = sqlite3_open_v2(filename, ppDb, flags, zVfs); if (err != SQLITE_OK) { return err; } - PostHandle(*ppDb); + PostHandle(isExists, *ppDb); return err; } @@ -715,6 +1090,7 @@ DB_API DistributedDB::DBStatus RegisterClientObserver(sqlite3 *db, const ClientO if (errCode != DistributedDB::DBStatus::OK) { return DistributedDB::DB_ERROR; } + std::lock_guard lock(g_clientObserverMutex); g_clientObserverMap[hashFileName] = clientObserver; return DistributedDB::OK; @@ -732,6 +1108,7 @@ DB_API DistributedDB::DBStatus UnRegisterClientObserver(sqlite3 *db) if (errCode != DistributedDB::DBStatus::OK) { return DistributedDB::DB_ERROR; } + std::lock_guard lock(g_clientObserverMutex); auto it = g_clientObserverMap.find(hashFileName); if (it != g_clientObserverMap.end()) { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h index e50d00e7145d43eef07469ba5e2d3d663b7421e3..a5a2c46a8e7ec64a91a7fd6049724b0c547c3c4c 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h @@ -102,7 +102,9 @@ public: const std::string &targetID) const override; int CheckAndInitQueryCondition(QueryObject &query) const override; - void RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action); + int RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, + const RelationalObserverAction &action); + int UnRegisterObserverAction(uint64_t connectionId, const StoreObserver *observer); void TriggerObserverAction(const std::string &deviceName, ChangedData &&changedData, bool isChangedData) override; int CreateDistributedDeviceTable(const std::string &device, const RelationalSyncStrategy &syncStrategy) override; @@ -132,16 +134,19 @@ public: int Rollback() override; - int GetUploadCount(const std::string &tableName, const Timestamp ×tamp, const bool isCloudForcePush, + int GetUploadCount(const QuerySyncObject &query, const Timestamp ×tamp, bool isCloudForcePush, int64_t &count) override; int FillCloudGid(const CloudSyncData &data) override; - int GetCloudData(const TableSchema &tableSchema, const Timestamp &beginTime, + int GetCloudData(const TableSchema &tableSchema, const QuerySyncObject &object, const Timestamp &beginTime, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) override; int GetCloudDataNext(ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) override; + int GetCloudGid(const TableSchema &tableSchema, const QuerySyncObject &querySyncObject, bool isCloudForcePush, + std::vector &cloudGid) override; + int ReleaseCloudDataToken(ContinueToken &continueStmtToken) override; int ChkSchema(const TableName &tableName) override; @@ -174,6 +179,7 @@ public: void ReleaseContinueToken(ContinueToken &continueStmtToken) const override; + int CheckQueryValid(const QuerySyncObject &query) override; private: SQLiteSingleVerRelationalStorageExecutor *GetHandle(bool isWrite, int &errCode, OperatePerm perm = OperatePerm::NORMAL_PERM) const; @@ -196,7 +202,7 @@ private: std::function onSchemaChanged_; mutable std::mutex onSchemaChangedMutex_; std::mutex dataChangeDeviceMutex_; - std::map dataChangeCallbackMap_; + std::map> dataChangeCallbackMap_; std::function heartBeatListener_; mutable std::mutex heartBeatMutex_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_meta_data.h b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_meta_data.h index f714b75a22a6a1c41553850002c28f8ec5c04cee..28b316e9c7847f726122b7c18ae16e38686966fe 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_meta_data.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_meta_data.h @@ -48,7 +48,7 @@ private: int ReadMarkFromMeta(const TableName &tableName); int WriteMarkToMeta(const TableName &tableName, Timestamp localmark, std::string &cloudMark); - int SerializeMark(Timestamp localMark, std::string &cloudMark, Value &blobMeta); + int SerializeMark(const Timestamp localMark, const std::string &cloudMark, Value &blobMeta); int DeserializeMark(Value &blobMark, CloudMetaValue &cloudMetaValue); Key GetPrefixTableName(const TableName &tableName); @@ -58,4 +58,4 @@ private: }; } // namespace DistributedDB -#endif // DISTRIBUTEDDB_TYPES_EXPORT_H +#endif // CLOUD_META_DATA_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h index fc42a2842251f351e3cc89efca9f61ed6a395e2b..0f52100f1151d807ca27af27a6376d5eb2b87b1b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h @@ -51,7 +51,7 @@ public: bool sortByUpper = false); static bool IsContainsPrimaryKey(const TableSchema &tableSchema); static std::vector GetCloudAsset(const TableSchema &tableSchema); - static int GetAssetFieldsFromSchema(const TableSchema &tableSchema, VBucket &vBucket, + static int GetAssetFieldsFromSchema(const TableSchema &tableSchema, const VBucket &vBucket, std::vector &fields); static void ObtainAssetFromVBucket(const VBucket &vBucket, VBucket &asset); static AssetOpType StatusToFlag(AssetStatus status); diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h index efb597d66de1585cfcb8b468b0f3ec449dd5e388..cdd1c9593ff3ef39a3431399594496fe11a2c212 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#ifndef RELATIONAL_DB_CLOUD_INTERFACE_H -#define RELATIONAL_DB_CLOUD_INTERFACE_H +#ifndef ICLOUD_SYNC_STORAGE_INTERFACE_H +#define ICLOUD_SYNC_STORAGE_INTERFACE_H #include "cloud/cloud_db_types.h" #include "data_transformer.h" +#include "query_sync_object.h" #include "sqlite_utils.h" #include "store_observer.h" @@ -64,16 +65,19 @@ public: virtual int Rollback() = 0; - virtual int GetUploadCount(const std::string &tableName, const Timestamp ×tamp, const bool isCloudForcePush, + virtual int GetUploadCount(const QuerySyncObject &query, const Timestamp ×tamp, bool isCloudForcePush, int64_t &count) = 0; virtual int FillCloudGid(const CloudSyncData &data) = 0; - virtual int GetCloudData(const TableSchema &tableSchema, const Timestamp &beginTime, + virtual int GetCloudData(const TableSchema &tableSchema, const QuerySyncObject &object, const Timestamp &beginTime, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) = 0; virtual int GetCloudDataNext(ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) = 0; + virtual int GetCloudGid(const TableSchema &tableSchema, const QuerySyncObject &querySyncObject, + bool isCloudForcePush, std::vector &cloudGid) = 0; + virtual int ReleaseCloudDataToken(ContinueToken &continueStmtToken) = 0; virtual int GetInfoByPrimaryKeyOrGid(const std::string &tableName, const VBucket &vBucket, @@ -94,7 +98,9 @@ public: virtual int FillCloudGidAndAsset(OpType opType, const CloudSyncData &data) = 0; virtual std::string GetIdentify() const = 0; + + virtual int CheckQueryValid(const QuerySyncObject &query) = 0; }; } -#endif //RELATIONAL_DB_CLOUD_INTERFACE_H +#endif // ICLOUD_SYNC_STORAGE_INTERFACE_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h index a5ad5d113533e0d66f05fa9285c2a09d2f2731b3..c4b44b26bb5fc507d63ec3b2903baa136b91f4cc 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h @@ -59,15 +59,15 @@ public: virtual int RemoveDeviceData(const std::string &device) = 0; virtual int RemoveDeviceData(const std::string &device, const std::string &tableName) = 0; virtual int DoClean(ClearMode mode) = 0; - virtual void RegisterObserverAction(const RelationalObserverAction &action) = 0; + virtual int RegisterObserverAction(const StoreObserver *observer, const RelationalObserverAction &action) = 0; + virtual int UnRegisterObserverAction(const StoreObserver *observer) = 0; virtual int RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, std::shared_ptr &result) = 0; virtual int SetCloudDB(const std::shared_ptr &cloudDb) = 0; virtual int SetCloudDbSchema(const DataBaseSchema &schema) = 0; virtual int SetIAssetLoader(const std::shared_ptr &loader) = 0; - virtual int Sync(const std::vector &devices, SyncMode mode, const Query &query, - const SyncProcessCallback &onProcess, int64_t waitTime) = 0; + virtual int Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) = 0; virtual int GetStoreInfo(std::string &userId, std::string &appId, std::string &storeId) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h index 618a5e82640c1206a5d3c6959651e94a90ee8c38..331bfff2e7da5c0b26c06e5f01d6d216419f83d1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h @@ -25,6 +25,7 @@ #include "cloud/schema_mgr.h" #include "data_transformer.h" #include "icloud_sync_storage_interface.h" +#include "query_sync_object.h" namespace DistributedDB { @@ -54,13 +55,21 @@ public: int GetUploadCount(const std::string &tableName, const Timestamp ×tamp, const bool isCloudForcePush, int64_t &count); + int GetUploadCount(const QuerySyncObject &query, const Timestamp &localMark, bool isCloudForcePush, + int64_t &count); + int FillCloudGid(const CloudSyncData &data); int GetCloudData(const std::string &tableName, const Timestamp &timeRange, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult); + int GetCloudData(const QuerySyncObject &querySyncObject, const Timestamp &timeRange, + ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult); + int GetCloudDataNext(ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) const; + int GetCloudGid(const QuerySyncObject &querySyncObject, bool isCloudForcePush, std::vector &cloudGid); + int GetInfoByPrimaryKeyOrGid(const std::string &tableName, const VBucket &vBucket, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo); @@ -76,7 +85,7 @@ public: int GetPrimaryColNamesWithAssetsFields(const TableName &tableName, std::vector &colNames, std::vector &assetFields); - int NotifyChangedData(const std::string deviceName, ChangedData &&changedData); + int NotifyChangedData(const std::string &deviceName, ChangedData &&changedData); int ReleaseContinueToken(ContinueToken &continueStmtToken); @@ -89,7 +98,6 @@ public: std::string GetIdentify() const; int CleanWaterMark(const TableName &tableName); - protected: void Init(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_meta_data.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_meta_data.cpp index 4e8ea71464363a2ab500361c1316ef9f76e0dd79..41aa74c70e759da355fb8a8192c72daf40bee0d0 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_meta_data.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_meta_data.cpp @@ -62,7 +62,7 @@ int CloudMetaData::GetCloudWaterMark(const TableName &tableName, std::string &cl int CloudMetaData::SetLocalWaterMark(const TableName &tableName, Timestamp localMark) { std::lock_guard lock(cloudMetaMutex_); - std::string cloudMark = ""; + std::string cloudMark; auto iter = cloudMetaVals_.find(tableName); if (iter != cloudMetaVals_.end()) { cloudMark = iter->second.cloudMark; @@ -134,7 +134,7 @@ int CloudMetaData::WriteMarkToMeta(const TableName &tableName, Timestamp localma return store_->PutMetaData(GetPrefixTableName(tableName), blobMetaVal); } -int CloudMetaData::SerializeMark(Timestamp localMark, std::string &cloudMark, Value &blobMeta) +int CloudMetaData::SerializeMark(const Timestamp localMark, const std::string &cloudMark, Value &blobMeta) { uint64_t length = Parcel::GetUInt64Len() + Parcel::GetStringLen(cloudMark); blobMeta.resize(length); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp index d13b1e3b8299d304c55f8908e9d55cea96f36f20..d912ed9fe4b35100664de70b2c175139bc88c3d7 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp @@ -239,9 +239,7 @@ int CloudStorageUtils::TextToVector(const VBucket &vBucket, const Field &field, return -E_CLOUD_ERROR; } if (collateType == CollateType::COLLATE_NOCASE) { - for (auto &c : val) { - c = static_cast(std::toupper(c)); - } + std::transform(val.begin(), val.end(), val.begin(), ::toupper); } else if (collateType == CollateType::COLLATE_RTRIM) { DBCommon::RTrim(val); } @@ -329,7 +327,7 @@ std::map CloudStorageUtils::GetCloudPrimaryKeyFieldMap(const return pkMap; } -int CloudStorageUtils::GetAssetFieldsFromSchema(const TableSchema &tableSchema, VBucket &vBucket, +int CloudStorageUtils::GetAssetFieldsFromSchema(const TableSchema &tableSchema, const VBucket &vBucket, std::vector &fields) { for (const auto &field: tableSchema.fields) { @@ -688,16 +686,17 @@ bool CloudStorageUtils::IsVbucketContainsAllPK(const VBucket &vBucket, const std static bool IsViolationOfConstraints(const std::string &name, const std::vector &fieldInfos) { for (const auto &field : fieldInfos) { - if (name == field.GetFieldName()) { - if (field.GetStorageType() == StorageType::STORAGE_TYPE_REAL) { - LOGE("[ConstraintsCheckForCloud] Not support create distributed table with real primary key."); - return true; - } else if (field.IsAssetType() || field.IsAssetsType()) { - LOGE("[ConstraintsCheckForCloud] Not support create distributed table with asset primary key."); - return true; - } else { - return false; - } + if (name != field.GetFieldName()) { + continue; + } + if (field.GetStorageType() == StorageType::STORAGE_TYPE_REAL) { + LOGE("[ConstraintsCheckForCloud] Not support create distributed table with real primary key."); + return true; + } else if (field.IsAssetType() || field.IsAssetsType()) { + LOGE("[ConstraintsCheckForCloud] Not support create distributed table with asset primary key."); + return true; + } else { + return false; } } return false; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp index 4f871dd7916c43e874e81817f819e37198bd2dcc..7587cf2352b6652e553f43b6452cc46ea1948ba7 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp @@ -80,7 +80,7 @@ int SchemaMgr::CompareFieldSchema(std::map &primaryKeys, FieldIn } cloudColNames.emplace(cloudField.colName); } - if (primaryKeys.size() > 0 && !(primaryKeys.size() == 1 && primaryKeys[0] == CloudDbConstant::ROW_ID_FIELD_NAME)) { + if (!primaryKeys.empty() && !(primaryKeys.size() == 1 && primaryKeys[0] == CloudDbConstant::ROW_ID_FIELD_NAME)) { LOGE("Local schema contain extra primary key:%d", -E_SCHEMA_MISMATCH); return -E_SCHEMA_MISMATCH; } @@ -122,7 +122,6 @@ bool SchemaMgr::CompareType(const FieldInfo &localField, const Field &cloudField default: return false; } - return false; } bool SchemaMgr::CompareNullable(const FieldInfo &localField, const Field &cloudField) diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp index 9bd0b60c3c11573350d6cf6baa2f244ace65e02b..d87b4b693a35322c610c575364b0943e6be5c992 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.cpp @@ -81,7 +81,7 @@ KvDBObserverHandle *GenericKvDBConnection::RegisterObserver(unsigned mode, } std::lock_guard lockGuard(observerListLock_); - if (observerList_.size() >= MAX_OBSERVER_COUNT) { + if (observerList_.size() >= DBConstant::MAX_OBSERVER_COUNT) { errCode = -E_MAX_LIMITS; LOGE("The number of observers has been larger than 'MAX_OBSERVER_COUNT'!"); return nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h index 09c1088bf01cc292dbd629c35a767a6017c0713e..05a8c8533073e27cc4fe28ad9d4c69a6b93610a5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb_connection.h @@ -108,9 +108,6 @@ private: int RegisterObserverForOneType(int type, const Key &key, const KvDBObserverAction &action, NotificationChain::Listener *&listener); - // Soft limit of a connection observer count. - static constexpr int MAX_OBSERVER_COUNT = 8; - bool isSafeDeleted_; std::mutex observerListLock_; std::list observerList_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 4bb003985f177925d415a2c89a1f30148a93c3ed..c4f868e43cd20d6ae5d6010aaa4214fc97531980 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -681,10 +681,49 @@ int RelationalSyncAbleStorage::GetCompressionAlgo(std::set &a return E_OK; } -void RelationalSyncAbleStorage::RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action) +int RelationalSyncAbleStorage::RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, + const RelationalObserverAction &action) { std::lock_guard lock(dataChangeDeviceMutex_); - dataChangeCallbackMap_[connectionId] = action; + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + if (it->second.find(observer) != it->second.end()) { + LOGE("obsever already registered"); + return -E_ALREADY_SET; + } + if (it->second.size() >= DBConstant::MAX_OBSERVER_COUNT) { + LOGE("The number of relational observers has been over limit"); + return -E_MAX_LIMITS; + } + it->second[observer] = action; + } else { + dataChangeCallbackMap_[connectionId][observer] = action; + } + LOGI("register relational observer ok"); + return E_OK; +} + +int RelationalSyncAbleStorage::UnRegisterObserverAction(uint64_t connectionId, const StoreObserver *observer) +{ + if (observer == nullptr) { + EraseDataChangeCallback(connectionId); + return E_OK; + } + std::lock_guard lock(dataChangeDeviceMutex_); + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + auto action = it->second.find(observer); + if (action != it->second.end()) { + it->second.erase(action); + LOGI("unregister relational observer."); + if (it->second.empty()) { + dataChangeCallbackMap_.erase(it); + LOGI("observer for this delegate is zero now"); + } + return E_OK; + } + } + return -E_NOT_FOUND; } void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceName, @@ -693,14 +732,19 @@ void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceN IncObjRef(this); int taskErrCode = RuntimeContext::GetInstance()->ScheduleTask([this, deviceName, changedData, isChangedData] () mutable { + LOGD("begin to trigger relational observer."); + int observerCnt = 0; std::lock_guard lock(dataChangeDeviceMutex_); - LOGD("begin to trigger observer, size = %zu(include null observer)", dataChangeCallbackMap_.size()); for (const auto &item : dataChangeCallbackMap_) { - if (item.second != nullptr) { - ChangedData observerChangeData = changedData; - item.second(deviceName, std::move(observerChangeData), isChangedData); + for (const auto &action : item.second) { + if (action.second != nullptr) { + observerCnt++; + ChangedData observerChangeData = changedData; + action.second(deviceName, std::move(observerChangeData), isChangedData); + } } } + LOGD("relational observer size = %d", observerCnt); DecObjRef(this); }); if (taskErrCode != E_OK) { @@ -941,15 +985,17 @@ int RelationalSyncAbleStorage::Rollback() return errCode; } -int RelationalSyncAbleStorage::GetUploadCount(const std::string &tableName, const Timestamp ×tamp, - const bool isCloudForcePush, int64_t &count) +int RelationalSyncAbleStorage::GetUploadCount(const QuerySyncObject &query, const Timestamp ×tamp, + bool isCloudForcePush, int64_t &count) { int errCode = E_OK; auto *handle = GetHandleExpectTransaction(false, errCode); if (handle == nullptr) { return errCode; } - errCode = handle->GetUploadCount(tableName, timestamp, isCloudForcePush, count); + QuerySyncObject queryObj = query; + queryObj.SetSchema(GetSchemaInfo()); + errCode = handle->GetUploadCount(timestamp, isCloudForcePush, queryObj, count); if (transactionHandle_ == nullptr) { ReleaseHandle(handle); } @@ -983,17 +1029,17 @@ int RelationalSyncAbleStorage::FillCloudGid(const CloudSyncData &data) return errCode; } -int RelationalSyncAbleStorage::GetCloudData(const TableSchema &tableSchema, const Timestamp &beginTime, - ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) +int RelationalSyncAbleStorage::GetCloudData(const TableSchema &tableSchema, const QuerySyncObject &querySyncObject, + const Timestamp &beginTime, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { if (transactionHandle_ == nullptr) { LOGE(" the transaction has not been started"); return -E_INVALID_DB; } SyncTimeRange syncTimeRange = { .beginTime = beginTime }; - QueryObject queryObject; - queryObject.SetTableName(tableSchema.name); - auto token = new (std::nothrow) SQLiteSingleVerRelationalContinueToken(syncTimeRange, queryObject); + QuerySyncObject query = querySyncObject; + query.SetSchema(GetSchemaInfo()); + auto token = new (std::nothrow) SQLiteSingleVerRelationalContinueToken(syncTimeRange, query); if (token == nullptr) { LOGE("[SingleVerNStore] Allocate continue token failed."); return -E_OUT_OF_MEMORY; @@ -1027,6 +1073,26 @@ int RelationalSyncAbleStorage::GetCloudDataNext(ContinueToken &continueStmtToken return errCode; } +int RelationalSyncAbleStorage::GetCloudGid(const TableSchema &tableSchema, const QuerySyncObject &querySyncObject, + bool isCloudForcePush, std::vector &cloudGid) +{ + int errCode = E_OK; + auto *handle = GetHandle(false, errCode); + if (handle == nullptr) { + return errCode; + } + Timestamp beginTime = 0u; + SyncTimeRange syncTimeRange = { .beginTime = beginTime }; + QuerySyncObject query = querySyncObject; + query.SetSchema(GetSchemaInfo()); + errCode = handle->GetSyncCloudGid(query, syncTimeRange, isCloudForcePush, cloudGid); + ReleaseHandle(handle); + if (errCode != E_OK) { + LOGE("[RelationalSyncAbleStorage] GetCloudGid failed %d", errCode); + } + return errCode; +} + int RelationalSyncAbleStorage::ReleaseCloudDataToken(ContinueToken &continueStmtToken) { if (continueStmtToken == nullptr) { @@ -1216,6 +1282,7 @@ void RelationalSyncAbleStorage::EraseDataChangeCallback(uint64_t connectionId) auto it = dataChangeCallbackMap_.find(connectionId); if (it != dataChangeCallbackMap_.end()) { dataChangeCallbackMap_.erase(it); + LOGI("erase all observer for this delegate."); } } @@ -1229,5 +1296,29 @@ void RelationalSyncAbleStorage::ReleaseContinueToken(ContinueToken &continueStmt delete token; continueStmtToken = nullptr; } + +int RelationalSyncAbleStorage::CheckQueryValid(const QuerySyncObject &query) +{ + int errCode = E_OK; + auto *handle = GetHandle(false, errCode); + if (handle == nullptr) { + return errCode; + } + errCode = handle->CheckQueryObjectLegal(query); + if (errCode != E_OK) { + ReleaseHandle(handle); + return errCode; + } + QuerySyncObject queryObj = query; + queryObj.SetSchema(GetSchemaInfo()); + int64_t count = 0; + errCode = handle->GetUploadCount(UINT64_MAX, false, queryObj, count); + ReleaseHandle(handle); + if (errCode != E_OK) { + LOGE("[RelationalSyncAbleStorage] CheckQueryValid failed %d", errCode); + return -E_INVALID_ARGS; + } + return errCode; +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp index 07fb30965db54807d9b56e3b6a6c607f4ac5fdfe..a83a6e8067c9f2e45bf8a0560aad9e0d464f8b3a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_data_inserter.cpp @@ -191,8 +191,8 @@ int RelationalSyncDataInserter::GetDeleteLogStmt(sqlite3 *db, sqlite3_stmt *&stm int RelationalSyncDataInserter::GetDeleteSyncDataStmt(sqlite3 *db, sqlite3_stmt *&stmt) { - std::string sql = "DELETE FROM '" + insertTableName_ + "' WHERE rowid IN (" - "SELECT data_key FROM " + DBConstant::RELATIONAL_PREFIX + localTable_.GetTableName() + "_log "; + std::string sql = "DELETE FROM '" + insertTableName_ + "' WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + + " IN (SELECT data_key FROM " + DBConstant::RELATIONAL_PREFIX + localTable_.GetTableName() + "_log "; if (mode_ == DistributedTableMode::COLLABORATION) { sql += "WHERE hash_key=?);"; } else { @@ -235,12 +235,12 @@ int RelationalSyncDataInserter::PrepareStatement(sqlite3 *db, SaveSyncDataStmt & { int errCode = GetSaveLogStatement(db, stmt.saveLogStmt, stmt.queryStmt); if (errCode != E_OK) { - LOGE("Get statement failed. err=%d", errCode); + LOGE("Get save log statement failed. err=%d", errCode); return errCode; } errCode = GetInsertStatement(db, stmt.saveDataStmt); if (errCode != E_OK) { - LOGE("Get statement failed. err=%d", errCode); + LOGE("Get insert statement failed. err=%d", errCode); } return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/cloud_sync_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/cloud_sync_log_table_manager.cpp index fa6eec4ef99e2479261fbbcb22285be96ccdb7f7..c485bdd57c003efa67cc45a147aac39c58a6857d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/cloud_sync_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/cloud_sync_log_table_manager.cpp @@ -14,6 +14,7 @@ */ #include "cloud_sync_log_table_manager.h" +#include "cloud/cloud_db_constant.h" #include "db_common.h" namespace DistributedDB { @@ -27,13 +28,16 @@ std::string CloudSyncLogTableManager::CalcPrimaryKeyHash(const std::string &refe std::string pkName = table.GetPrimaryKey().at(0); if (pkName == "rowid") { std::string collateStr = std::to_string(static_cast(CollateType::COLLATE_NONE)); - sql = "calc_hash(" + references + "'" + table.GetPrimaryKey().at(0) + "', " + collateStr + ")"; + // we use _rowid_ to reference sqlite inner rowid to avoid rowid is a user defined column, + // user can't create distributed table with column named "_rowid_" + sql = "calc_hash(" + references + "'" + std::string(DBConstant::SQLITE_INNER_ROWID) + "', " + + collateStr + ")"; } else { if (fieldInfos.find(pkName) == fieldInfos.end()) { return sql; } std::string collateStr = std::to_string(static_cast(fieldInfos.at(pkName).GetCollateType())); - sql = "calc_hash(" + references + "'" + table.GetPrimaryKey().at(0) + "', " + collateStr + ")"; + sql = "calc_hash(" + references + "'" + pkName + "', " + collateStr + ")"; } } else { std::set primaryKeySet; // we need sort primary key by upper name @@ -63,12 +67,19 @@ void CloudSyncLogTableManager::GetIndexSql(const TableInfo &table, std::vector0 FROM "; - insertTrigger += logTblName + " where hash_key = " + CalcPrimaryKeyHash("NEW.", table, identity); - insertTrigger += ") THEN (select cloud_gid from " + logTblName + " where hash_key = "; + insertTrigger += logTblName + " WHERE hash_key = " + CalcPrimaryKeyHash("NEW.", table, identity); + insertTrigger += ") THEN (SELECT cloud_gid FROM " + logTblName + " WHERE hash_key = "; insertTrigger += CalcPrimaryKeyHash("NEW.", table, identity) + ") ELSE '' END);\n"; - insertTrigger += "select client_observer('" + tableName + "', NEW.rowid, 0);\n"; + insertTrigger += "SELECT client_observer('" + tableName + "', NEW." + std::string(DBConstant::SQLITE_INNER_ROWID); + insertTrigger += ", 0);\n"; insertTrigger += "END;"; return insertTrigger; } @@ -109,8 +121,9 @@ std::string CloudSyncLogTableManager::GetUpdateTrigger(const TableInfo &table, c updateTrigger += "BEGIN\n"; // if user change the primary key, we can still use gid to identify which one is updated updateTrigger += "\t UPDATE " + logTblName; updateTrigger += " SET timestamp=get_raw_sys_time(), device='', flag=0x02"; - updateTrigger += " WHERE data_key = OLD.rowid;\n"; - updateTrigger += "select client_observer('" + tableName + "', OLD.rowid, 1);\n"; + updateTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";\n"; + updateTrigger += "SELECT client_observer('" + tableName + "', OLD." + std::string(DBConstant::SQLITE_INNER_ROWID); + updateTrigger += ", 1);\n"; updateTrigger += "END;"; return updateTrigger; } @@ -127,9 +140,9 @@ std::string CloudSyncLogTableManager::GetDeleteTrigger(const TableInfo &table, c deleteTrigger += "BEGIN\n"; deleteTrigger += "\t UPDATE " + GetLogTableName(table); deleteTrigger += " SET data_key=-1,flag=0x03,timestamp=get_raw_sys_time()"; - deleteTrigger += " WHERE data_key = OLD.rowid;"; + deleteTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";"; // -1 is rowid when data is deleted, 2 means change type is delete(ClientChangeType) - deleteTrigger += "select client_observer('" + tableName + "', -1, 2);\n"; + deleteTrigger += "SELECT client_observer('" + tableName + "', -1, 2);\n"; deleteTrigger += "END;"; return deleteTrigger; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp index 26468e70b6d2500884943b54ea49cf30482c0d6d..64d79568352789ccbaefb1ffbd79bbe0261c854d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/collaboration_log_table_manager.cpp @@ -27,9 +27,10 @@ std::string CollaborationLogTableManager::CalcPrimaryKeyHash(const std::string & { std::string sql; if (IsCollaborationWithoutKey(table)) { - sql = "calc_hash('" + identity + "'||calc_hash(" + references + "rowid, 0), 0)"; + sql = "calc_hash('" + identity + "'||calc_hash(" + references + std::string(DBConstant::SQLITE_INNER_ROWID) + + ", 0), 0)"; } else { - if (table.GetIdentifyKey().size() == 1) { + if (table.GetIdentifyKey().size() == 1u) { sql = "calc_hash(" + references + "'" + table.GetIdentifyKey().at(0) + "', 0)"; } else { sql = "calc_hash("; @@ -55,7 +56,7 @@ std::string CollaborationLogTableManager::GetInsertTrigger(const TableInfo &tabl insertTrigger += "BEGIN\n"; insertTrigger += "\t INSERT OR REPLACE INTO " + logTblName; insertTrigger += " (data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key)"; - insertTrigger += " VALUES (new.rowid, '', '',"; + insertTrigger += " VALUES (new." + std::string(DBConstant::SQLITE_INNER_ROWID) + ", '', '',"; insertTrigger += " get_sys_time(0), get_last_time(),"; insertTrigger += " CASE WHEN (SELECT count(*)<>0 FROM " + logTblName + " WHERE hash_key=" + CalcPrimaryKeyHash("NEW.", table, identity) + " AND flag&0x02=0x02) THEN 0x22 ELSE 0x02 END,"; @@ -73,19 +74,20 @@ std::string CollaborationLogTableManager::GetUpdateTrigger(const TableInfo &tabl updateTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata "; updateTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n"; updateTrigger += "BEGIN\n"; - if (table.GetIdentifyKey().size() == 1 && table.GetIdentifyKey().at(0) == "rowid") { + if (table.GetIdentifyKey().size() == 1u && table.GetIdentifyKey().at(0) == "rowid") { // primary key is rowid, it can't be changed updateTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; updateTrigger += " SET timestamp=get_sys_time(0), device='', flag=0x22"; - updateTrigger += " WHERE data_key = OLD.rowid;"; + updateTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";"; } else { // primary key may be changed, so we need to set the old log record deleted, then insert or replace a new // log record(if primary key not change, insert or replace will modify the log record we set deleted in previous // step) updateTrigger += "\t UPDATE " + logTblName; updateTrigger += " SET data_key=-1, timestamp=get_sys_time(0), device='', flag=0x03"; - updateTrigger += " WHERE data_key = OLD.rowid;\n"; - updateTrigger += "\t INSERT OR REPLACE INTO " + logTblName + " VALUES (NEW.rowid, '', '', get_sys_time(0), " + updateTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID)+ ";\n"; + updateTrigger += "\t INSERT OR REPLACE INTO " + logTblName + " VALUES (NEW." + + std::string(DBConstant::SQLITE_INNER_ROWID) + ", '', '', get_sys_time(0), " "get_last_time(), CASE WHEN (" + CalcPrimaryKeyHash("NEW.", table, identity) + " != " + CalcPrimaryKeyHash("NEW.", table, identity) + ") THEN 0x02 ELSE 0x22 END, " + CalcPrimaryKeyHash("NEW.", table, identity) + ", '');\n"; @@ -105,7 +107,7 @@ std::string CollaborationLogTableManager::GetDeleteTrigger(const TableInfo &tabl deleteTrigger += "BEGIN\n"; deleteTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; deleteTrigger += " SET data_key=-1,flag=0x03,timestamp=get_sys_time(0)"; - deleteTrigger += " WHERE data_key = OLD.rowid;"; + deleteTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";"; deleteTrigger += "END;"; return deleteTrigger; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.cpp index 0fed477c30b8efc5d087eb1ba67219cf78709cf7..2e0baaf4530c77f7453ff6e6ec103ccd896ee8c5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.cpp @@ -51,15 +51,20 @@ void QueryObject::SetAttrWithQueryObjNodes() } } else if (iter.operFlag == QueryObjType::ORDERBY) { hasOrderBy_ = true; - } else if (symbolType == PREFIXKEY_SYMBOL) { + } else if (symbolType == SymbolType::PREFIXKEY_SYMBOL) { hasPrefixKey_ = true; - } else if (symbolType == IN_KEYS_SYMBOL) { + } else if (symbolType == SymbolType::IN_KEYS_SYMBOL) { hasInKeys_ = true; } } } QueryObject::QueryObject(const Query &query) + : QueryObject(GetQueryInfo::GetQueryExpression(query)) +{ +} + +QueryObject::QueryObject(const QueryExpression &queryExpression) : initialized_(false), limit_(INVALID_LIMIT), offset_(0), @@ -69,7 +74,7 @@ QueryObject::QueryObject(const Query &query) hasInKeys_(false), orderByCounts_(0) { - QueryExpression queryExpressions = GetQueryInfo::GetQueryExpression(query); + QueryExpression queryExpressions = queryExpression; queryObjNodes_ = queryExpressions.GetQueryExpression(); SetAttrWithQueryObjNodes(); isValid_ = queryExpressions.GetErrFlag(); @@ -80,7 +85,7 @@ QueryObject::QueryObject(const Query &query) keys_ = queryExpressions.GetKeys(); sortType_ = static_cast(queryExpressions.GetSortType()); tables_ = queryExpressions.GetTables(); - isWithDeviceSyncQuery_ = queryExpressions.GetIsDeviceSyncQuery(); + validStatus = queryExpressions.GetExpressionStatus(); } QueryObject::QueryObject(const std::list &queryObjNodes, const std::vector &prefixKey, @@ -219,13 +224,13 @@ int QueryObject::ParseNode(const std::list::iterator &iter) } switch (SqliteQueryHelper::GetSymbolType(iter->operFlag)) { - case COMPARE_SYMBOL: - case RELATIONAL_SYMBOL: - case RANGE_SYMBOL: + case SymbolType::COMPARE_SYMBOL: + case SymbolType::RELATIONAL_SYMBOL: + case SymbolType::RANGE_SYMBOL: return CheckEqualFormat(iter); - case LINK_SYMBOL: + case SymbolType::LINK_SYMBOL: return CheckLinkerFormat(iter); - case PREFIXKEY_SYMBOL: { + case SymbolType::PREFIXKEY_SYMBOL: { if (hasPrefixKey_) { LOGE("Only filter by prefix key once!!"); return -E_INVALID_QUERY_FORMAT; @@ -236,9 +241,9 @@ int QueryObject::ParseNode(const std::list::iterator &iter) } return E_OK; } - case SUGGEST_INDEX_SYMBOL: + case SymbolType::SUGGEST_INDEX_SYMBOL: return CheckSuggestIndexFormat(iter); - case IN_KEYS_SYMBOL: { + case SymbolType::IN_KEYS_SYMBOL: { if (hasInKeys_) { LOGE("Only filter by keys in once!!"); return -E_INVALID_QUERY_FORMAT; @@ -277,8 +282,9 @@ int QueryObject::CheckLinkerBefore(const std::list::iterator &iter { auto preIter = std::prev(iter, 1); SymbolType symbolType = SqliteQueryHelper::GetSymbolType(preIter->operFlag); - if (symbolType != COMPARE_SYMBOL && symbolType != RELATIONAL_SYMBOL && symbolType != LOGIC_SYMBOL && - symbolType != RANGE_SYMBOL && symbolType != PREFIXKEY_SYMBOL && symbolType != IN_KEYS_SYMBOL) { + if (symbolType != SymbolType::COMPARE_SYMBOL && symbolType != SymbolType::RELATIONAL_SYMBOL && + symbolType != SymbolType::LOGIC_SYMBOL && symbolType != SymbolType::RANGE_SYMBOL && + symbolType != SymbolType::PREFIXKEY_SYMBOL && symbolType != SymbolType::IN_KEYS_SYMBOL) { LOGE("Must be a comparison operation before the connective! operFlag = %s", VNAME(preIter->operFlag)); return -E_INVALID_QUERY_FORMAT; } @@ -310,7 +316,7 @@ int QueryObject::CheckEqualFormat(const std::list::iterator &iter) } if (schemaFieldType == FieldType::LEAF_FIELD_BOOL && - SqliteQueryHelper::GetSymbolType(iter->operFlag) == COMPARE_SYMBOL && + SqliteQueryHelper::GetSymbolType(iter->operFlag) == SymbolType::COMPARE_SYMBOL && iter->operFlag != QueryObjType::EQUALTO && iter->operFlag != QueryObjType::NOT_EQUALTO) { // bool can == or != LOGE("Bool forbid compare!!!"); return -E_INVALID_QUERY_FORMAT; @@ -318,7 +324,8 @@ int QueryObject::CheckEqualFormat(const std::list::iterator &iter) auto nextIter = std::next(iter, 1); if (nextIter != queryObjNodes_.end()) { SymbolType symbolType = SqliteQueryHelper::GetSymbolType(nextIter->operFlag); - if (symbolType == RELATIONAL_SYMBOL || symbolType == COMPARE_SYMBOL || symbolType == RANGE_SYMBOL) { + if (symbolType == SymbolType::RELATIONAL_SYMBOL || symbolType == SymbolType::COMPARE_SYMBOL || + symbolType == SymbolType::RANGE_SYMBOL) { LOGE("After Compare you need, You need the conjunction like and or for connecting!"); return -E_INVALID_QUERY_FORMAT; } @@ -331,7 +338,7 @@ int QueryObject::CheckLinkerFormat(const std::list::iterator &iter auto itPre = iter; for (; itPre != queryObjNodes_.begin(); itPre = std::prev(itPre, 1)) { SymbolType symbolType = SqliteQueryHelper::GetSymbolType(std::prev(itPre, 1)->operFlag); - if (symbolType != PREFIXKEY_SYMBOL && symbolType != IN_KEYS_SYMBOL) { + if (symbolType != SymbolType::PREFIXKEY_SYMBOL && symbolType != SymbolType::IN_KEYS_SYMBOL) { break; } } @@ -345,7 +352,8 @@ int QueryObject::CheckLinkerFormat(const std::list::iterator &iter return -E_INVALID_QUERY_FORMAT; } SymbolType symbolType = SqliteQueryHelper::GetSymbolType(nextIter->operFlag); - if (symbolType == INVALID_SYMBOL || symbolType == LINK_SYMBOL || symbolType == SPECIAL_SYMBOL) { + if (symbolType == SymbolType::INVALID_SYMBOL || symbolType == SymbolType::LINK_SYMBOL || + symbolType == SymbolType::SPECIAL_SYMBOL) { LOGE("Must be followed by comparison operation! operflag[%u], symbolType[%u]", static_cast(nextIter->operFlag), static_cast(symbolType)); return -E_INVALID_QUERY_FORMAT; @@ -392,7 +400,8 @@ int QueryObject::CheckOrderByFormat(const std::list::iterator &ite int QueryObject::CheckLimitFormat(const std::list::iterator &iter) const { auto next = std::next(iter, 1); - if (next != queryObjNodes_.end() && SqliteQueryHelper::GetSymbolType(next->operFlag) != SUGGEST_INDEX_SYMBOL) { + if (next != queryObjNodes_.end() && SqliteQueryHelper::GetSymbolType(next->operFlag) != + SymbolType::SUGGEST_INDEX_SYMBOL) { LOGE("Limit should be last node or just before suggest-index node!"); return -E_INVALID_QUERY_FORMAT; } @@ -499,5 +508,45 @@ SortType QueryObject::GetSortType() const { return sortType_; } + +int QueryObject::CheckPrimaryKey(const std::map &primaryKeyMap) const +{ + if (primaryKeyMap.size() == 1 && primaryKeyMap.begin()->second == "rowid") { + return -E_NOT_SUPPORT; + } + std::set pkSet; + for (const auto &item : primaryKeyMap) { + std::string pk = item.second; + std::transform(pk.begin(), pk.end(), pk.begin(), ::tolower); + pkSet.insert(pk); + } + std::set queryPkSet; + for (const auto &queryObjNode : queryObjNodes_) { + if (queryObjNode.operFlag != QueryObjType::IN && queryObjNode.operFlag != QueryObjType::EQUALTO) { + continue; + } + std::string field = queryObjNode.fieldName; + std::transform(field.begin(), field.end(), field.begin(), ::tolower); + if (pkSet.find(field) == pkSet.end()) { + LOGE("[Query] query without pk!"); + return -E_NOT_SUPPORT; + } + if (queryObjNode.type == QueryValueType::VALUE_TYPE_DOUBLE) { + LOGE("[Query] query with pk double!"); + return -E_NOT_SUPPORT; + } + queryPkSet.insert(field); + } + if (queryPkSet.size() != pkSet.size()) { + LOGE("[Query] pk count is different! query %zu schema %zu", queryPkSet.size(), pkSet.size()); + return -E_NOT_SUPPORT; + } + return E_OK; +} + +std::vector QueryObject::GetQueryExpressions(const Query &query) +{ + return GetQueryInfo::GetQueryExpression(query).GetQueryExpressions(); +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.h index 27e98a6f19aa2851f02e485bfd621e98f8c09575..4d1b663c2bb4d1cfd765b40648aa8b4d0b41ff9e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_object.h @@ -63,6 +63,8 @@ public: SortType GetSortType() const; + int CheckPrimaryKey(const std::map &primaryMap) const; + #ifdef RELATIONAL_STORE int SetSchema(const RelationalSchemaObject &schemaObj); // The interface can only be used in relational query. #endif @@ -70,6 +72,8 @@ public: // For continue token, once sync may not get all sync data, use AddOffset to continue last query void SetLimit(int limit, int offset); protected: + explicit QueryObject(const QueryExpression &queryExpression); + static std::vector GetQueryExpressions(const Query &query); std::list queryObjNodes_; std::vector prefixKey_; std::string tableName_ = "sync_data"; @@ -81,7 +85,7 @@ protected: bool initialized_ = false; // use function need after init bool isTableNameSpecified_ = false; std::vector tables_; - bool isWithDeviceSyncQuery_ = true; + int validStatus = E_OK; private: int Parse(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.cpp index 392b4ebc7aa8533bc3797d8697bb51c91dbded23..44666396df9dddfccbe115f89a82c12b2e6179af 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.cpp @@ -15,6 +15,7 @@ #include "query_sync_object.h" +#include "cloud/cloud_db_constant.h" #include "db_common.h" #include "db_errno.h" #include "log_print.h" @@ -96,6 +97,10 @@ QuerySyncObject::QuerySyncObject(const Query &query) : QueryObject(query) {} +QuerySyncObject::QuerySyncObject(const DistributedDB::QueryExpression &expression) + : QueryObject(expression) +{} + QuerySyncObject::~QuerySyncObject() {} @@ -238,6 +243,23 @@ int QuerySyncObject::SerializeData(Parcel &parcel, uint32_t softWareVersion) return E_OK; } +void QuerySyncObject::SetCloudGid(const std::vector &cloudGid) +{ + QueryObjNode objNode; + objNode.operFlag = QueryObjType::OR; + objNode.type = QueryValueType::VALUE_TYPE_NULL; + queryObjNodes_.push_back(objNode); + objNode.operFlag = QueryObjType::IN; + objNode.fieldName = CloudDbConstant::GID_FIELD; + objNode.type = QueryValueType::VALUE_TYPE_STRING; + for (const auto &gid : cloudGid) { + FieldValue fieldValue; + fieldValue.stringValue = gid; + objNode.fieldValue.emplace_back(fieldValue); + } + queryObjNodes_.emplace_back(objNode); +} + namespace { int DeSerializeVersion1Data(uint32_t version, Parcel &parcel, std::string &tableName, std::set &keys) { @@ -367,8 +389,123 @@ std::vector QuerySyncObject::GetRelationTableNames() const return tables_; } -bool QuerySyncObject::GetIsDeviceSyncQuery() const +int QuerySyncObject::GetValidStatus() const +{ + return validStatus; +} + +bool QuerySyncObject::IsContainQueryNodes() const +{ + return !queryObjNodes_.empty(); +} + +bool QuerySyncObject::IsInValueOutOfLimit() const { - return isWithDeviceSyncQuery_; + for (const auto &queryObjNode : queryObjNodes_) { + if ((queryObjNode.operFlag == QueryObjType::IN) && + (queryObjNode.fieldValue.size() > DBConstant::MAX_IN_COUNT)) { + return false; + } + } + return true; +} + +std::vector QuerySyncObject::GetQuerySyncObject(const DistributedDB::Query &query) +{ + std::vector res; + const auto &expressions = QueryObject::GetQueryExpressions(query); + for (const auto &item : expressions) { + res.push_back(QuerySyncObject(item)); + } + return res; +} + +int QuerySyncObject::ParserQueryNodes(const Bytes &bytes, std::vector &queryNodes) +{ + QuerySyncObject tmp; + Bytes parcelBytes = bytes; + Parcel parcel(parcelBytes.data(), parcelBytes.size()); + int errCode = DeSerializeData(parcel, tmp); + if (errCode != E_OK) { + return errCode; + } + for (const auto &objNode: tmp.queryObjNodes_) { + QueryNode node; + errCode = TransformToQueryNode(objNode, node); + if (errCode != E_OK) { + return errCode; + } + queryNodes.push_back(std::move(node)); + } + return E_OK; +} + +int QuerySyncObject::TransformToQueryNode(const QueryObjNode &objNode, QueryNode &node) +{ + int errCode = TransformValueToType(objNode, node.fieldValue); + if (errCode != E_OK) { + LOGE("[Query] transform value to type failed %d", errCode); + return errCode; + } + node.fieldName = objNode.fieldName; + return TransformNodeType(objNode, node); +} + +int QuerySyncObject::TransformValueToType(const QueryObjNode &objNode, std::vector &types) +{ + for (const auto &value: objNode.fieldValue) { + switch (objNode.type) { + case QueryValueType::VALUE_TYPE_STRING: + types.emplace_back(value.stringValue); + break; + case QueryValueType::VALUE_TYPE_BOOL: + types.emplace_back(value.boolValue); + break; + case QueryValueType::VALUE_TYPE_NULL: + types.emplace_back(Nil()); + break; + case QueryValueType::VALUE_TYPE_INTEGER: + case QueryValueType::VALUE_TYPE_LONG: + types.emplace_back(static_cast(value.integerValue)); + break; + case QueryValueType::VALUE_TYPE_DOUBLE: + types.emplace_back(value.doubleValue); + break; + case QueryValueType::VALUE_TYPE_INVALID: + default: + return -E_INVALID_ARGS; + } + } + return E_OK; +} + +int QuerySyncObject::TransformNodeType(const QueryObjNode &objNode, QueryNode &node) +{ + int errCode = E_OK; + switch (objNode.operFlag) { + case QueryObjType::IN: + node.type = QueryNodeType::IN; + break; + case QueryObjType::OR: + node.type = QueryNodeType::OR; + break; + case QueryObjType::AND: + node.type = QueryNodeType::AND; + break; + case QueryObjType::EQUALTO: + node.type = QueryNodeType::EQUAL_TO; + break; + case QueryObjType::BEGIN_GROUP: + node.type = QueryNodeType::BEGIN_GROUP; + break; + case QueryObjType::END_GROUP: + node.type = QueryNodeType::END_GROUP; + break; + default: + LOGE("[Query] not support type %d", static_cast(objNode.operFlag)); + errCode = -E_NOT_SUPPORT; + node.type = QueryNodeType::ILLEGAL; + } + return errCode; } } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.h index ec1931138ca54e84bae05790241e744fa0e075f9..c0fb607fa262614b4b72cef172d910ed91f7834e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/query_sync_object.h @@ -45,6 +45,7 @@ public: std::string GetIdentify() const; int SerializeData(Parcel &parcel, uint32_t softWareVersion); + void SetCloudGid(const std::vector &cloudGid); // should call Parcel.IsError() to Get result. static int DeSerializeData(Parcel &parcel, QuerySyncObject &queryObj); uint32_t CalculateParcelLen(uint32_t softWareVersion) const; @@ -53,14 +54,28 @@ public: std::vector GetRelationTableNames() const; - bool GetIsDeviceSyncQuery() const; + int GetValidStatus() const; + bool IsContainQueryNodes() const; + + bool IsInValueOutOfLimit() const; + + static std::vector GetQuerySyncObject(const Query &query); + + static int ParserQueryNodes(const Bytes &bytes, std::vector &queryNodes); private: + explicit QuerySyncObject(const QueryExpression &expression); uint32_t CalculateLen() const; uint32_t CalculateIdentifyLen() const; int GetObjContext(ObjContext &objContext) const; uint32_t GetVersion() const; + static int TransformToQueryNode(const QueryObjNode &objNode, QueryNode &node); + + static int TransformValueToType(const QueryObjNode &objNode, std::vector &types); + + static int TransformNodeType(const QueryObjNode &objNode, QueryNode &node); + mutable std::string identify_; }; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp index 87c7f2e35ce9ade2e65ac1ce2b9426979daf64ab..5f4ae1d9ed5f62c00eb49876ad6030fa53da9b1a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp @@ -131,14 +131,14 @@ int SqliteRelationalDatabaseUpgrader::UpgradeTrigger(const std::string &logTable return E_OK; } -static bool inline NoNeedUpdateLogTable(const std::string &logTableVersion) +static bool inline NeedUpdateLogTable(const std::string &logTableVersion) { - return logTableVersion > DBConstant::LOG_TABLE_VERSION_2; + return logTableVersion < DBConstant::LOG_TABLE_VERSION_3; } int SqliteRelationalDatabaseUpgrader::UpgradeLogTable(const std::string &logTableVersion) { - if (NoNeedUpdateLogTable(logTableVersion)) { + if (!NeedUpdateLogTable(logTableVersion)) { LOGD("[Relational][Upgrade] No need upgrade log table."); return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 9006091cf61ed2adff3148648666350ac44bcf52..777f4310b0fe7cf41d9e4ce8f55f19c02af8bdde 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -506,9 +506,11 @@ int SQLiteRelationalStore::RemoveDeviceData() // erase watermark first int errCode = EraseAllDeviceWatermark(tableNameList); if (errCode != E_OK) { + LOGE("remove watermark failed %d", errCode); return errCode; } - auto *handle = GetHandleAndStartTransaction(errCode); + SQLiteSingleVerRelationalStorageExecutor *handle = nullptr; + errCode = GetHandleAndStartTransaction(handle); if (handle == nullptr) { return errCode; } @@ -585,9 +587,15 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std return RemoveDeviceDataInner(hashDeviceId, device, tableName, isNeedHash); } -void SQLiteRelationalStore::RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action) +int SQLiteRelationalStore::RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, + const RelationalObserverAction &action) { - storageEngine_->RegisterObserverAction(connectionId, action); + return storageEngine_->RegisterObserverAction(connectionId, observer, action); +} + +int SQLiteRelationalStore::UnRegisterObserverAction(uint64_t connectionId, const StoreObserver *observer) +{ + return storageEngine_->UnRegisterObserverAction(connectionId, observer); } int SQLiteRelationalStore::StopLifeCycleTimer() @@ -788,7 +796,7 @@ int SQLiteRelationalStore::EraseAllDeviceWatermark(const std::vectorStartTransaction(TransactType::IMMEDIATE); if (errCode != E_OK) { + LOGE("start transaction failed %d", errCode); ReleaseHandle(handle); - return nullptr; + return errCode; } - return handle; + return errCode; } int SQLiteRelationalStore::RemoveDeviceDataInner(const std::string &mappingDev, const std::string &device, @@ -840,9 +851,11 @@ int SQLiteRelationalStore::RemoveDeviceDataInner(const std::string &mappingDev, // erase watermark first int errCode = syncAbleEngine_->EraseDeviceWaterMark(hashDev, false, tableName); if (errCode != E_OK) { + LOGE("erase watermark failed %d", errCode); return errCode; } - auto *handle = GetHandleAndStartTransaction(errCode); + SQLiteSingleVerRelationalStorageExecutor *handle = nullptr; + errCode = GetHandleAndStartTransaction(handle); if (handle == nullptr) { return errCode; } @@ -851,7 +864,7 @@ int SQLiteRelationalStore::RemoveDeviceDataInner(const std::string &mappingDev, TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap if (errCode != E_OK) { LOGE("delete device data failed. %d", errCode); - goto END; + tables.clear(); } for (const auto &it : tables) { @@ -864,7 +877,6 @@ int SQLiteRelationalStore::RemoveDeviceDataInner(const std::string &mappingDev, } } -END: if (errCode != E_OK) { (void)handle->Rollback(); ReleaseHandle(handle); @@ -940,47 +952,149 @@ int SQLiteRelationalStore::ChkSchema(const TableName &tableName) return storageEngine_->ChkSchema(tableName); } -int SQLiteRelationalStore::Sync(const std::vector &devices, SyncMode mode, - const Query &query, const SyncProcessCallback &onProcess, int64_t waitTime) +int SQLiteRelationalStore::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) +{ + int errCode = CheckBeforeSync(option); + if (errCode != E_OK) { + return errCode; + } + CloudSyncer::CloudTaskInfo info; + FillSyncInfo(option, onProcess, info); + return cloudSyncer_->Sync(info); +} + +int SQLiteRelationalStore::CheckBeforeSync(const CloudSyncOption &option) { if (cloudSyncer_ == nullptr) { LOGE("[RelationalStore] cloudSyncer was not initialized when sync"); return -E_INVALID_DB; } - QuerySyncObject querySyncObject(query); - if (querySyncObject.GetIsDeviceSyncQuery()) { - LOGE("[RelationalStore] cloudSyncer was not support other query"); - return -E_NOT_SUPPORT; - } - const auto tableNames = querySyncObject.GetRelationTableNames(); - if (tableNames.empty()) { - LOGE("[RelationalStore] sync with empty table"); + if (option.waitTime > DBConstant::MAX_SYNC_TIMEOUT || option.waitTime < DBConstant::INFINITE_WAIT) { return -E_INVALID_ARGS; } - SecurityOption option; - int errCode = storageEngine_->GetSecurityOption(option); + int errCode = CheckQueryValid(option.priorityTask, option.query); + if (errCode != E_OK) { + return errCode; + } + SecurityOption securityOption; + errCode = storageEngine_->GetSecurityOption(securityOption); if (errCode != E_OK && errCode != -E_NOT_SUPPORT) { return -E_SECURITY_OPTION_CHECK_ERROR; } - if (errCode == E_OK && option.securityLabel == S4) { + if (errCode == E_OK && securityOption.securityLabel == S4) { return -E_SECURITY_OPTION_CHECK_ERROR; } + return E_OK; +} + +int SQLiteRelationalStore::CheckQueryValid(bool priorityTask, const Query &query) +{ + QuerySyncObject syncObject(query); + int errCode = syncObject.GetValidStatus(); + if (errCode != E_OK) { + LOGE("[RelationalStore] query is invalid or not support %d", errCode); + return errCode; + } + std::vector object = QuerySyncObject::GetQuerySyncObject(query); + if (!priorityTask && !object.empty()) { + LOGE("[RelationalStore] not support normal sync with query"); + return -E_NOT_SUPPORT; + } + const auto tableNames = syncObject.GetRelationTableNames(); + if (priorityTask && !tableNames.empty()) { + LOGE("[RelationalStore] not support priority sync with from tables"); + return -E_NOT_SUPPORT; + } + for (const auto &tableName : tableNames) { + QuerySyncObject querySyncObject; + querySyncObject.SetTableName(tableName); + object.push_back(querySyncObject); + } + std::vector syncTableNames; + for (const auto &item : object) { + std::string tableName = item.GetRelationTableName(); + syncTableNames.emplace_back(tableName); + } + errCode = CheckTableName(syncTableNames); + if (errCode != E_OK) { + return errCode; + } + errCode = CheckObjectValid(priorityTask, object); + return errCode; +} + +int SQLiteRelationalStore::CheckObjectValid(bool priorityTask, const std::vector &object) +{ + int errCode = E_OK; + RelationalSchemaObject localSchema = sqliteStorageEngine_->GetSchema(); + for (const auto &item : object) { + if (priorityTask && !item.IsContainQueryNodes()) { + LOGE("[RelationalStore] not support priority sync with full table"); + return -E_INVALID_ARGS; + } + errCode = storageEngine_->CheckQueryValid(item); + if (errCode != E_OK) { + return errCode; + } + if (!priorityTask) { + continue; + } + if (!item.IsInValueOutOfLimit()) { + LOGE("[RelationalStore] not support priority sync in count out of limit"); + return -E_MAX_LIMITS; + } + std::string tableName = item.GetRelationTableName(); + TableInfo tableInfo = localSchema.GetTable(tableName); + if (!tableInfo.Empty()) { + const std::map& primaryKeyMap = tableInfo.GetPrimaryKey(); + errCode = item.CheckPrimaryKey(primaryKeyMap); + if (errCode != E_OK) { + return errCode; + } + } + } + return errCode; +} + +int SQLiteRelationalStore::CheckTableName(const std::vector &tableNames) +{ + if (tableNames.empty()) { + LOGE("[RelationalStore] sync with empty table"); + return -E_INVALID_ARGS; + } for (const auto &table: tableNames) { - errCode = ChkSchema(table); + int errCode = ChkSchema(table); if (errCode != E_OK) { LOGE("[RelationalStore] schema check failed when sync"); return errCode; } } - std::vector syncTable; - std::set addTable; - for (const auto &table: tableNames) { - if (addTable.find(table) == addTable.end()) { - addTable.insert(table); - syncTable.push_back(table); + return E_OK; +} + +void SQLiteRelationalStore::FillSyncInfo(const CloudSyncOption &option, const SyncProcessCallback &onProcess, + CloudSyncer::CloudTaskInfo &info) +{ + auto syncObject = QuerySyncObject::GetQuerySyncObject(option.query); + if (syncObject.empty()) { + QuerySyncObject querySyncObject(option.query); + info.table = querySyncObject.GetRelationTableNames(); + for (const auto &item: info.table) { + QuerySyncObject object(Query::Select()); + object.SetTableName(item); + info.queryList.push_back(object); + } + } else { + for (auto &item: syncObject) { + info.table.push_back(item.GetRelationTableName()); + info.queryList.push_back(std::move(item)); } } - return cloudSyncer_->Sync(devices, mode, syncTable, onProcess, waitTime); + info.devices = option.devices; + info.mode = option.mode; + info.callback = onProcess; + info.timeout = option.waitTime; + info.priorityTask = option.priorityTask; } } #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h index b4057c73895211184fcbef24b3256c83440c8934..cb7e3086404e6270667e1435a7299beea4c1caf4 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h @@ -67,7 +67,9 @@ public: int RemoveDeviceData(); int RemoveDeviceData(const std::string &device, const std::string &tableName); - void RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action); + int RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, + const RelationalObserverAction &action); + int UnRegisterObserverAction(uint64_t connectionId, const StoreObserver *observer); int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier); std::string GetStorePath() const override; @@ -89,8 +91,7 @@ public: int ChkSchema(const TableName &tableName); - int Sync(const std::vector &devices, SyncMode mode, const Query &query, - const SyncProcessCallback &onProcess, int64_t waitTime); + int Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess); private: void ReleaseResources(); @@ -120,7 +121,7 @@ private: std::string GetDevTableName(const std::string &device, const std::string &hashDev) const; - SQLiteSingleVerRelationalStorageExecutor *GetHandleAndStartTransaction(int &errCode) const; + int GetHandleAndStartTransaction(SQLiteSingleVerRelationalStorageExecutor *&handle) const; int RemoveDeviceDataInner(const std::string &mappingDev, const std::string &device, const std::string &tableName, bool isNeedHash); @@ -129,6 +130,17 @@ private: std::vector GetAllDistributedTableName(); + int CheckBeforeSync(const CloudSyncOption &option); + + int CheckQueryValid(bool priorityTask, const Query &query); + + int CheckObjectValid(bool priorityTask, const std::vector &object); + + int CheckTableName(const std::vector &tableNames); + + void FillSyncInfo(const CloudSyncOption &option, const SyncProcessCallback &onProcess, + CloudSyncer::CloudTaskInfo &info); + // use for sync Interactive std::shared_ptr syncAbleEngine_ = nullptr; // For storage operate sync function // use ref obj same as kv diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp index 78d3bfd151179b6e03783e068478caee5ce9c67b..fd7273dd60f40c97917e1db967cd93d967b72449 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp @@ -251,7 +251,9 @@ int SQLiteRelationalStoreConnection::SyncToDevice(SyncInfo &info) syncParam.isQuerySync = true; syncParam.relationOnComplete = info.onComplete; syncParam.syncQuery = QuerySyncObject(info.query); - syncParam.onFinalize = [this]() { DecObjRef(this); }; + syncParam.onFinalize = [this]() { + DecObjRef(this); + }; if (syncParam.syncQuery.GetSortType() != SortType::NONE) { LOGE("not support order by timestamp"); DecObjRef(this); @@ -276,9 +278,15 @@ int SQLiteRelationalStoreConnection::RegisterLifeCycleCallback(const DatabaseLif return store->RegisterLifeCycleCallback(notifier); } -void SQLiteRelationalStoreConnection::RegisterObserverAction(const RelationalObserverAction &action) +int SQLiteRelationalStoreConnection::RegisterObserverAction(const StoreObserver *observer, + const RelationalObserverAction &action) +{ + return static_cast(store_)->RegisterObserverAction(GetConnectionId(), observer, action); +} + +int SQLiteRelationalStoreConnection::UnRegisterObserverAction(const StoreObserver *observer) { - static_cast(store_)->RegisterObserverAction(GetConnectionId(), action); + return static_cast(store_)->UnRegisterObserverAction(GetConnectionId(), observer); } int SQLiteRelationalStoreConnection::RemoteQuery(const std::string &device, const RemoteCondition &condition, @@ -330,11 +338,10 @@ int SQLiteRelationalStoreConnection::SetIAssetLoader(const std::shared_ptr &devices, SyncMode mode, const Query &query, - const SyncProcessCallback &onProcess, int64_t waitTime) +int SQLiteRelationalStoreConnection::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) { auto *store = GetDB(); if (store == nullptr) { @@ -350,7 +357,7 @@ int SQLiteRelationalStoreConnection::Sync(const std::vector &device } IncObjRef(this); } - int errCode = store->Sync(devices, mode, query, onProcess, waitTime); + int errCode = store->Sync(option, onProcess); DecObjRef(this); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h index 111b0a7753f585abfca001b981bc2554a6c0ccfb..ea773ad9e85c0bd394f0266b9a58b74705ac8d5a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h @@ -43,15 +43,15 @@ public: 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; + int RegisterObserverAction(const StoreObserver *observer, const RelationalObserverAction &action) override; + int UnRegisterObserverAction(const StoreObserver *observer) override; int RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, std::shared_ptr &result) override; int SetCloudDB(const std::shared_ptr &cloudDb) override; int SetCloudDbSchema(const DataBaseSchema &schema) override; int SetIAssetLoader(const std::shared_ptr &loader) override; - int Sync(const std::vector &devices, SyncMode mode, const Query &query, - const SyncProcessCallback &onProcess, int64_t waitTime) override; + int Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) override; int GetStoreInfo(std::string &userId, std::string &appId, std::string &storeId) override; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp index 5e18bbff059ff8638ad940ce15e9423122cd7a00..92d436afbe24275ccecfc4eddd96b695e93e16d8 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp @@ -74,7 +74,7 @@ std::vector SQLiteRelationalUtils::GetSelectValues(sqlite3_stmt *stmt std::vector values; for (int cid = 0, colCount = sqlite3_column_count(stmt); cid < colCount; ++cid) { DataValue value; - (void)GetDataValueByType(stmt, cid, value); + (void)GetDataValueByType(stmt, cid, value); values.emplace_back(std::move(value)); } return values; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp index e48cad430deaf8673cd2c621409edb715518e3a4..5d29e74b95d1ee47efd89702b6ba5f819fb03bce 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp @@ -156,7 +156,7 @@ int SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor *handle, cons return errCode; } -int SaveSyncTableTypeToMeta(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, +int SaveSyncTableTypeAndDropFlagToMeta(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, TableSyncType syncType) { Key key; @@ -166,6 +166,12 @@ int SaveSyncTableTypeToMeta(SQLiteSingleVerRelationalStorageExecutor *handle, co int errCode = handle->PutKvData(key, value); if (errCode != E_OK) { LOGE("Save sync table type to meta table failed. %d", errCode); + return errCode; + } + DBCommon::StringToVector(DBConstant::TABLE_IS_DROPPED + tableName, key); + errCode = handle->DeleteMetaData({ key }); + if (errCode != E_OK) { + LOGE("Save table drop flag to meta table failed. %d", errCode); } return errCode; } @@ -238,7 +244,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin return errCode; } - errCode = SaveSyncTableTypeToMeta(handle, tableName, tableSyncType); + errCode = SaveSyncTableTypeAndDropFlagToMeta(handle, tableName, tableSyncType); if (errCode != E_OK) { (void)handle->Rollback(); return errCode; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/split_device_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/split_device_log_table_manager.cpp index e3176bd234d31bea4630917d5c5fb479a02500c3..84039aa003778f5cfad888c8131a69dbecb13ef5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/split_device_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/split_device_log_table_manager.cpp @@ -44,7 +44,7 @@ std::string SplitDeviceLogTableManager::GetInsertTrigger(const TableInfo &table, insertTrigger += "BEGIN\n"; insertTrigger += "\t INSERT OR REPLACE INTO " + logTblName; insertTrigger += " (data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key)"; - insertTrigger += " VALUES (new.rowid, '', '',"; + insertTrigger += " VALUES (new." + std::string(DBConstant::SQLITE_INNER_ROWID) + ", '', '',"; insertTrigger += " get_sys_time(0), get_last_time(),"; insertTrigger += " CASE WHEN (SELECT count(*)<>0 FROM " + logTblName + " WHERE hash_key=" + CalcPrimaryKeyHash("NEW.", table, identity) + " AND flag&0x02=0x02) THEN 0x22 ELSE 0x02 END,"; @@ -73,7 +73,8 @@ std::string SplitDeviceLogTableManager::GetUpdateTrigger(const TableInfo &table, updateTrigger += "\t UPDATE " + logTblName; updateTrigger += " SET data_key=-1,timestamp=get_sys_time(0), device='', flag=0x03"; updateTrigger += " WHERE hash_key=" + CalcPrimaryKeyHash("OLD.", table, identity) + " AND flag&0x02=0x02;\n"; - updateTrigger += "\t INSERT OR REPLACE INTO " + logTblName + " VALUES (NEW.rowid, '', '', get_sys_time(0), " + updateTrigger += "\t INSERT OR REPLACE INTO " + logTblName + " VALUES (NEW." + + std::string(DBConstant::SQLITE_INNER_ROWID) + ", '', '', get_sys_time(0), " "get_last_time(), CASE WHEN (" + CalcPrimaryKeyHash("NEW.", table, identity) + " != " + CalcPrimaryKeyHash("NEW.", table, identity) + ") THEN 0x02 ELSE 0x22 END, " + CalcPrimaryKeyHash("NEW.", table, identity) + ", '');\n"; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp index dff4fd898fc464b5212808a6a05ae4a424b229e2..132d5674e2aeae48df8f208eb23c40984ca84106 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp @@ -102,7 +102,7 @@ std::string GetSelectAndFromClauseForRDB(const std::string &tableName, const std sql.pop_back(); } sql += " FROM '" + tableName + "' AS a INNER JOIN " + DBConstant::RELATIONAL_PREFIX + tableName + "_log AS b " - "ON a.rowid=b.data_key "; + "ON a." + std::string(DBConstant::SQLITE_INNER_ROWID) + "=b.data_key "; return sql; } @@ -159,11 +159,13 @@ bool SqliteQueryHelper::FilterSymbolToAddBracketLink(std::string &querySql, bool bool isNeedEndBracket = false; for (const auto &iter : queryObjNodes_) { SymbolType symbolType = GetSymbolType(iter.operFlag); - if (symbolType == COMPARE_SYMBOL || symbolType == RELATIONAL_SYMBOL || symbolType == RANGE_SYMBOL) { + if (symbolType == SymbolType::COMPARE_SYMBOL || symbolType == SymbolType::RELATIONAL_SYMBOL || + symbolType == SymbolType::RANGE_SYMBOL) { querySql += isNeedLink ? " AND (" : " ("; isNeedEndBracket = true; break; - } else if (symbolType == LOGIC_SYMBOL || symbolType == PREFIXKEY_SYMBOL || symbolType == IN_KEYS_SYMBOL) { + } else if (symbolType == SymbolType::LOGIC_SYMBOL || symbolType == SymbolType::PREFIXKEY_SYMBOL || + symbolType == SymbolType::IN_KEYS_SYMBOL) { continue; } else { break; @@ -187,7 +189,7 @@ int SqliteQueryHelper::ParseQueryObjNodeToSQL(bool isQueryForSync) int errCode = E_OK; for (const QueryObjNode &objNode : queryObjNodes_) { SymbolType symbolType = GetSymbolType(objNode.operFlag); - if (symbolType == SPECIAL_SYMBOL && isNeedEndBracket) { + if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) { querySql_ += ") "; isNeedEndBracket = false; } @@ -253,7 +255,7 @@ int SqliteQueryHelper::ToGetCountSql() int errCode = E_OK; for (const QueryObjNode &objNode : queryObjNodes_) { SymbolType symbolType = GetSymbolType(objNode.operFlag); - if (symbolType == SPECIAL_SYMBOL && isNeedEndBracket) { + if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) { countSql_ += ") "; isNeedEndBracket = false; } @@ -495,7 +497,7 @@ int SqliteQueryHelper::GetCountSqlStatement(sqlite3 *dbHandle, sqlite3_stmt *&co } for (const QueryObjNode &objNode : queryObjNodes_) { - if (GetSymbolType(objNode.operFlag) == SPECIAL_SYMBOL) { + if (GetSymbolType(objNode.operFlag) == SymbolType::SPECIAL_SYMBOL) { continue; } errCode = BindFieldValue(countStmt, objNode, index); @@ -636,7 +638,7 @@ std::string SqliteQueryHelper::MapRelationalSymbolToSql(const QueryObjNode &quer return ""; }; std::string sql = RELATIONAL_SYMBOL_TO_SQL.at(queryNode.operFlag) + MapValueToSql(queryNode, placeholder); - if (GetSymbolType(queryNode.operFlag) == RANGE_SYMBOL) { + if (GetSymbolType(queryNode.operFlag) == SymbolType::RANGE_SYMBOL) { sql += ")"; } return sql; @@ -718,7 +720,8 @@ std::string SqliteQueryHelper::MapCastFuncSql(const QueryObjNode &queryNode, con int SqliteQueryHelper::BindFieldValue(sqlite3_stmt *statement, const QueryObjNode &queryNode, int &index) const { SymbolType symbolType = GetSymbolType(queryNode.operFlag); - if (symbolType != COMPARE_SYMBOL && symbolType != RELATIONAL_SYMBOL && symbolType != RANGE_SYMBOL) { + if (symbolType != SymbolType::COMPARE_SYMBOL && symbolType != SymbolType::RELATIONAL_SYMBOL && + symbolType != SymbolType::RANGE_SYMBOL) { return E_OK; } @@ -760,15 +763,16 @@ int SqliteQueryHelper::ParseQueryExpression(const QueryObjNode &queryNode, std:: const std::string &accessStr, bool placeholder) { SymbolType symbolType = GetSymbolType(queryNode.operFlag); - if (symbolType == RANGE_SYMBOL && queryNode.fieldValue.size() > MAX_CONDITIONS_SIZE) { + if (symbolType == SymbolType::RANGE_SYMBOL && queryNode.fieldValue.size() > MAX_CONDITIONS_SIZE) { LOGE("[Query][Parse][Expression] conditions is too many!"); return -E_MAX_LIMITS; } - if (symbolType == COMPARE_SYMBOL || symbolType == RELATIONAL_SYMBOL || symbolType == RANGE_SYMBOL) { + if (symbolType == SymbolType::COMPARE_SYMBOL || symbolType == SymbolType::RELATIONAL_SYMBOL || + symbolType == SymbolType::RANGE_SYMBOL) { querySql += GetFieldShape(queryNode, accessStr); querySql += MapRelationalSymbolToSql(queryNode, placeholder); - } else if (symbolType == LOGIC_SYMBOL || symbolType == LINK_SYMBOL) { + } else if (symbolType == SymbolType::LOGIC_SYMBOL || symbolType == SymbolType::LINK_SYMBOL) { querySql += MapLogicSymbolToSql(queryNode); } else { querySql += MapKeywordSymbolToSql(queryNode); @@ -857,7 +861,7 @@ int SqliteQueryHelper::GetSubscribeCondition(const std::string &accessStr, std:: int errCode = E_OK; for (const QueryObjNode &objNode : queryObjNodes_) { SymbolType symbolType = GetSymbolType(objNode.operFlag); - if (symbolType == SPECIAL_SYMBOL && isNeedEndBracket) { + if (symbolType == SymbolType::SPECIAL_SYMBOL && isNeedEndBracket) { conditionStr += ") "; isNeedEndBracket = false; } @@ -1032,7 +1036,7 @@ int SqliteQueryHelper::GetRelationalSyncDataQuerySqlWithLimit(const std::vector< sql = GetRelationalSyncDataQueryHeader(fieldNames); sql += " FROM '" + tableName_ + "' AS a INNER JOIN "; sql += DBConstant::RELATIONAL_PREFIX + tableName_ + "_log"; - sql += " AS b ON (a.rowid = b.data_key)"; + sql += " AS b ON (a." + std::string(DBConstant::SQLITE_INNER_ROWID) + " = b.data_key)"; sql += " WHERE (b.flag&0x03=0x02)"; querySql_.clear(); // clear local query sql format @@ -1141,15 +1145,50 @@ int SqliteQueryHelper::GetRelationalCloudQueryStatement(sqlite3 *dbHandle, uint6 const std::vector &fields, const bool &isCloudForcePush, sqlite3_stmt *&statement) { std::string sql = GetRelationalCloudSyncDataQueryHeader(fields); + AppendCloudQuery(isCloudForcePush, sql); + return GetCloudQueryStatement(true, dbHandle, beginTime, sql, statement); +} + +int SqliteQueryHelper::GetCountRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, + bool isCloudForcePush, sqlite3_stmt *&statement) +{ + std::string sql = "SELECT COUNT(1) "; + AppendCloudQuery(isCloudForcePush, sql); + return GetCloudQueryStatement(false, dbHandle, beginTime, sql, statement); +} + +int SqliteQueryHelper::GetGidRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, + const std::vector &fields, bool isCloudForcePush, sqlite3_stmt *&statement) +{ + std::string sql = GetRelationalCloudSyncDataQueryHeader(fields); + AppendCloudGidQuery(isCloudForcePush, sql); + return GetCloudQueryStatement(false, dbHandle, beginTime, sql, statement); +} + +void SqliteQueryHelper::AppendCloudQuery(bool isCloudForcePush, std::string &sql) +{ sql += " FROM '" + DBCommon::GetLogTableName(tableName_) + "' AS b LEFT JOIN '"; - sql += tableName_ + "' AS a ON (a.rowid = b.data_key)"; + sql += tableName_ + "' AS a ON (a." + std::string(DBConstant::SQLITE_INNER_ROWID) + " = b.data_key)"; sql += isCloudForcePush ? " WHERE b.timestamp > ? AND (b.flag & 0x04 != 0x04)": " WHERE b.timestamp > ? AND (b.flag & 0x02 = 0x02)"; sql += " AND (b.cloud_gid != '' or"; // actually, b.cloud_gid will not be null. sql += " (b.cloud_gid == '' and (b.flag & 0x01 = 0))) "; +} +void SqliteQueryHelper::AppendCloudGidQuery(bool isCloudForcePush, std::string &sql) +{ + sql += " FROM '" + DBCommon::GetLogTableName(tableName_) + "' AS b LEFT JOIN '"; + sql += tableName_ + "' AS a ON (a." + std::string(DBConstant::SQLITE_INNER_ROWID) + " = b.data_key)"; + sql += isCloudForcePush ? " WHERE b.timestamp > ? AND (b.flag & 0x04 != 0x04)" : + " WHERE b.timestamp > ?"; + sql += " AND (b.cloud_gid != '') "; // actually, b.cloud_gid will not be null. +} + +int SqliteQueryHelper::GetCloudQueryStatement(bool useTimestampAlias, sqlite3 *dbHandle, uint64_t beginTime, + std::string &sql, sqlite3_stmt *&statement) +{ querySql_.clear(); // clear local query sql format - int errCode = ToQuerySyncSql(false, true); + int errCode = ToQuerySyncSql(false, useTimestampAlias); if (errCode != E_OK) { LOGE("To query sql fail! errCode[%d]", errCode); return errCode; @@ -1160,9 +1199,24 @@ int SqliteQueryHelper::GetRelationalCloudQueryStatement(sqlite3 *dbHandle, uint6 LOGE("[Query] Get statement fail!"); return -E_INVALID_QUERY_FORMAT; } - errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, beginTime); + errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, static_cast(beginTime)); if (errCode != E_OK) { + int resetRet = E_OK; + SQLiteUtils::ResetStatement(statement, true, resetRet); + if (resetRet != E_OK) { + LOGW("[Query] reset statement failed %d", resetRet); + } + return errCode; + } + int index = 2; // the query node begin with 2 in this sql + errCode = BindObjNodes(statement, index); + if (errCode != E_OK) { + LOGE("BindObjNodes failed %d", errCode); + int resetRet = E_OK; SQLiteUtils::ResetStatement(statement, true, errCode); + if (resetRet != E_OK) { + LOGW("[Query] reset statement failed %d", resetRet); + } } return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h index cee665f427a5c2fc7baac1ffe4540718241407fe..54d9f104e24451520559619b1740bddefc5b244d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h @@ -44,7 +44,7 @@ struct QueryObjInfo { SortType sortType_ = SortType::NONE; }; -enum SymbolType : uint32_t { +enum class SymbolType : uint32_t { INVALID_SYMBOL = 0x0000, COMPARE_SYMBOL = 0x0100, // relation symbol use to compare RELATIONAL_SYMBOL = 0x0200, @@ -103,6 +103,12 @@ public: int GetRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, const std::vector &fields, const bool &isCloudForcePush, sqlite3_stmt *&statement); + int GetCountRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, + bool isCloudForcePush, sqlite3_stmt *&statement); + + int GetGidRelationalCloudQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, + const std::vector &fields, bool isCloudForcePush, sqlite3_stmt *&statement); + private: int ToQuerySql(); int ToQuerySyncSql(bool hasSubQuery, bool useTimestampAlias = false); @@ -131,6 +137,13 @@ private: // Return the left string of symbol in compare clause. std::string GetFieldShape(const QueryObjNode &queryNode, const std::string &accessStr = ""); + void AppendCloudQuery(bool isCloudForcePush, std::string &sql); + + void AppendCloudGidQuery(bool isCloudForcePush, std::string &sql); + + int GetCloudQueryStatement(bool useTimestampAlias, sqlite3 *dbHandle, uint64_t beginTime, std::string &sql, + sqlite3_stmt *&statement); + SchemaObject schema_; std::list queryObjNodes_; std::vector prefixKey_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp index 9e7ef8f0945f07bec648b2418af63f28c807441c..0664750bbc0465f532df8c052d13d7003c649b39 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp @@ -415,7 +415,7 @@ int SQLiteSingleVerNaturalStore::GetAndInitStorageEngine(const KvDBProperties &k } if (storageEngine_->IsEngineCorrupted()) { - LOGE("[SqlSinStore][GetAndInitStorageEngine] database engine is corrupted or invalid passwd, stop open!"); + LOGE("[SqlSinStore][GetAndInitStorageEngine] database engine is corrupted or invalid key, stop open!"); return -E_INVALID_PASSWD_OR_CORRUPTED_DB; } @@ -1095,7 +1095,7 @@ SQLiteSingleVerStorageExecutor *SQLiteSingleVerNaturalStore::GetHandle(bool isWr CorruptNotify(); errCode = -E_INVALID_PASSWD_OR_CORRUPTED_DB; engineMutex_.unlock_shared(); // unlock when get handle failed. - LOGI("Handle is corrupted or invalid passwd, can not to get! errCode = [%d]", errCode); + LOGI("Handle is corrupted or invalid key, can not to get! errCode = [%d]", errCode); return nullptr; } @@ -1447,9 +1447,10 @@ int SQLiteSingleVerNaturalStore::Export(const std::string &filePath, const Ciphe // Exclusively write resources std::string localDev; - int errCode = GetAndResizeLocalIdentity(localDev); + GetAndResizeLocalIdentity(localDev); // The write handle is applied to prevent writing data during the export process. + int errCode = E_OK; SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); if (handle == nullptr) { return errCode; @@ -2498,7 +2499,7 @@ int SQLiteSingleVerNaturalStore::TryHandle() const return E_OK; } -int SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarget) const +void SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarget) const { int errCode = GetLocalIdentity(outTarget); if (errCode == -E_NOT_INIT) { @@ -2507,7 +2508,6 @@ int SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarge LOGE("Get local dev id err:%d", errCode); outTarget.resize(0); } - return errCode; } DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStore) } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h index 5b4223f45b50242b2bda4aa70974a91b7cc1f160..086a9a1e46dc22ef9a162b36161f9920bdb694a7 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h @@ -286,7 +286,7 @@ private: int RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify); - int GetAndResizeLocalIdentity(std::string &outTarget) const; + void GetAndResizeLocalIdentity(std::string &outTarget) const; DECLARE_OBJECT_TAG(SQLiteSingleVerNaturalStore); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_continue_token.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_continue_token.cpp index 5d1a5e10674c30f130bd4a4dc1c2a1e202eb5781..10dc010508a5cc0539e064902bc2230f5b22dc0b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_continue_token.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_continue_token.cpp @@ -117,7 +117,7 @@ int SQLiteSingleVerRelationalContinueToken::GetDeletedDataStmt(sqlite3 *db, sqli const std::string sql = GetDeletedDataSQL(); int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { - goto ERROR; + return errCode; } // bind stmt diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index af887bfb418206425026b395d7bc73ac835b093d..319b7b6cc744898104133262ec74865ae797cc94 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -32,14 +32,14 @@ namespace DistributedDB { namespace { -static constexpr const char* ROWID = "ROWID"; -static constexpr const char* TIMESTAMP = "TIMESTAMP"; -static constexpr const char* FLAG = "FLAG"; -static constexpr const char* DATAKEY = "DATA_KEY"; -static constexpr const char* DEVICE_FIELD = "DEVICE"; -static constexpr const char* CLOUD_GID_FIELD = "CLOUD_GID"; -static constexpr const char* FLAG_IS_CLOUD = "FLAG & 0x02 = 0"; // see if 1th bit of a flag is cloud -static constexpr const char* SET_FLAG_LOCAL = "FLAG | 0x02"; // set 1th bit of flag to one which is local +static constexpr const char *ROWID = "ROWID"; +static constexpr const char *TIMESTAMP = "TIMESTAMP"; +static constexpr const char *FLAG = "FLAG"; +static constexpr const char *DATAKEY = "DATA_KEY"; +static constexpr const char *DEVICE_FIELD = "DEVICE"; +static constexpr const char *CLOUD_GID_FIELD = "CLOUD_GID"; +static constexpr const char *FLAG_IS_CLOUD = "FLAG & 0x02 = 0"; // see if 1th bit of a flag is cloud +static constexpr const char *SET_FLAG_LOCAL = "FLAG | 0x02"; // set 1th bit of flag to one which is local static constexpr const int SET_FLAG_ZERO_MASK = 0x03; // clear 2th bit of flag static constexpr const int SET_FLAG_ONE_MASK = 0x04; // set 2th bit of flag static constexpr const int SET_CLOUD_FLAG = 0x05; // set 1th bit of flag to 0 @@ -77,6 +77,13 @@ int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode, Tabl LOGE("[CreateDistributedTable] Not support create distributed table without rowid."); return -E_NOT_SUPPORT; } + std::vector fieldInfos = table.GetFieldInfos(); + for (const auto &field : fieldInfos) { + if (DBCommon::CaseInsensitiveCompare(field.GetFieldName(), std::string(DBConstant::SQLITE_INNER_ROWID))) { + LOGE("[CreateDistributedTable] Not support create distributed table with _rowid_ column."); + return -E_NOT_SUPPORT; + } + } if (mode == DistributedTableMode::COLLABORATION || syncType == CLOUD_COOPERATION) { if (DBCommon::HasConstraint(trimedSql, "CHECK", " ,", " (")) { @@ -118,7 +125,8 @@ int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode, Tabl namespace { int GetExistedDataTimeOffset(sqlite3 *db, const std::string &tableName, bool isMem, int64_t &timeOffset) { - std::string sql = "SELECT get_sys_time(0) - max(rowid) - 1 FROM '" + tableName + "';"; + std::string sql = "SELECT get_sys_time(0) - max(" + std::string(DBConstant::SQLITE_INNER_ROWID) + ") - 1 FROM '" + + tableName + "';"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { @@ -135,7 +143,7 @@ int GetExistedDataTimeOffset(sqlite3 *db, const std::string &tableName, bool isM } int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 *db, const std::string &tableName, - const TableInfo &table, const std::string &calPrimaryKeyHash) + const std::string &calPrimaryKeyHash) { int64_t timeOffset = 0; int errCode = GetExistedDataTimeOffset(db, tableName, isMemDb_, timeOffset); @@ -144,8 +152,9 @@ int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 } std::string timeOffsetStr = std::to_string(timeOffset); std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log"; - std::string sql = "INSERT INTO " + logTable + - " SELECT rowid, '', '', " + timeOffsetStr + " + rowid, " + timeOffsetStr + " + rowid, 0x2, " + + std::string sql = "INSERT INTO " + logTable + " SELECT " + std::string(DBConstant::SQLITE_INNER_ROWID) + + ", '', '', " + timeOffsetStr + " + " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", " + + timeOffsetStr + " + " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", 0x2, " + calPrimaryKeyHash + ", ''" + " FROM '" + tableName + "' AS a WHERE 1=1;"; return SQLiteUtils::ExecuteRawSQL(db, sql); } @@ -189,7 +198,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(Distributed if (!isUpgraded) { std::string calPrimaryKeyHash = tableManager->CalcPrimaryKeyHash("a.", table, identity); - errCode = GeneLogInfoForExistedData(dbHandle_, tableName, table, calPrimaryKeyHash); + errCode = GeneLogInfoForExistedData(dbHandle_, tableName, calPrimaryKeyHash); if (errCode != E_OK) { return errCode; } @@ -218,7 +227,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std: } if (CheckTableConstraint(newTableInfo, mode, syncType)) { - LOGE("[UpgradeDistributedTable] Not support create distributed table without rowid."); + LOGE("[UpgradeDistributedTable] Not support create distributed table when violate constraints."); return -E_NOT_SUPPORT; } @@ -259,7 +268,6 @@ int GetDeviceTableName(sqlite3 *handle, const std::string &tableName, const std: sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(handle, checkSql, stmt); if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); return errCode; } @@ -347,7 +355,7 @@ IndexInfoMap GetChangedIndexes(const TableInfo &oldTableInfo, const TableInfo &n } else if (itOld->first < itNew->first) { indexes.insert({itOld->first, {}}); itOld++; - } else if (itOld->first > itNew->first) { + } else { indexes.insert({itNew->first, itNew->second}); itNew++; } @@ -433,7 +441,7 @@ int SQLiteSingleVerRelationalStorageExecutor::AlterAuxTableForUpgrade(const Tabl LOGE("upgrade indexes failed. %d", errCode); } - return E_OK; + return errCode; } int SQLiteSingleVerRelationalStorageExecutor::StartTransaction(TransactType type) @@ -569,6 +577,7 @@ int IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, } if (IsAbnormalData(data)) { LOGW("This data is abnormal, ignore it when upload"); + cloudSyncData.ignoredCount++; return E_OK; } cloudSyncData.insData.record.push_back(data); @@ -595,6 +604,19 @@ int IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, } return E_OK; } + +void GetCloudGid(sqlite3_stmt *logStatement, std::vector &cloudGid) +{ + if (sqlite3_column_text(logStatement, CLOUD_GID_INDEX) != nullptr) { + std::string gid = reinterpret_cast( + sqlite3_column_text(logStatement, CLOUD_GID_INDEX)); + if (!gid.empty()) { + cloudGid.emplace_back(gid); + } else { + LOGW("[Relational] Get cloud gid is null."); + } + } +} } static size_t GetDataItemSerialSize(DataItem &item, size_t appendLen) @@ -644,7 +666,7 @@ int SQLiteSingleVerRelationalStorageExecutor::PutKvData(const Key &key, const Va sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, INSERT_META_SQL, statement); if (errCode != E_OK) { - goto ERROR; + return errCode; } errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // 1 means key index @@ -1044,7 +1066,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetMissQueryData(sqlite3_stmt *ful } item.value = {}; item.flag |= DataItem::REMOTE_DEVICE_DATA_MISS_QUERY; - return errCode; + return E_OK; } namespace { @@ -1216,7 +1238,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedAllDeviceTableLog { std::string deleteLogSql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName + - "_log WHERE flag&0x02=0 and (cloud_gid = '' or cloud_gid is null)"; + "_log WHERE flag&0x02=0 AND (cloud_gid = '' OR cloud_gid IS NULL)"; return SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteLogSql); } @@ -1263,6 +1285,54 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedLogTable(const st return errCode; } +int SQLiteSingleVerRelationalStorageExecutor::IsTableOnceDropped(const std::string &tableName, int execCode, + bool &onceDropped) +{ + if (execCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // The table in schema was dropped + onceDropped = true; + return E_OK; + } + if (execCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + std::string keyStr = DBConstant::TABLE_IS_DROPPED + tableName; + Key key; + DBCommon::StringToVector(keyStr, key); + Value value; + + int errCode = GetKvData(key, value); + if (errCode == E_OK) { + // if user drop table first, then create again(but don't create distributed table), will reach this branch + onceDropped = true; + return E_OK; + } else if (errCode == -E_NOT_FOUND) { + onceDropped = false; + return E_OK; + } else { + LOGE("[IsTableOnceDropped] query is table dropped failed, %d", errCode); + return errCode; + } + } + return execCode; +} + +int SQLiteSingleVerRelationalStorageExecutor::CleanResourceForDroppedTable(const std::string &tableName) +{ + int errCode = DeleteDistributedDeviceTable({}, tableName); // Clean the auxiliary tables for the dropped table + if (errCode != E_OK) { + LOGE("Delete device tables for missing distributed table failed. %d", errCode); + return errCode; + } + errCode = DeleteDistributedLogTable(tableName); + if (errCode != E_OK) { + LOGE("Delete log tables for missing distributed table failed. %d", errCode); + return errCode; + } + errCode = DeleteMissTableTrigger(tableName); + if (errCode != E_OK) { + LOGE("Delete trigger for missing distributed table failed. %d", errCode); + } + return errCode; +} + int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(const std::vector &tableNames, std::vector &missingTables) { @@ -1271,9 +1341,10 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(cons } const std::string checkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?;"; sqlite3_stmt *stmt = nullptr; + int ret = E_OK; int errCode = SQLiteUtils::GetStatement(dbHandle_, checkSql, stmt); if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(stmt, true, ret); return errCode; } for (const auto &tableName : tableNames) { @@ -1284,26 +1355,22 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(cons } errCode = SQLiteUtils::StepWithRetry(stmt, false); - if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // The table in schema was dropped - errCode = DeleteDistributedDeviceTable({}, tableName); // Clean the auxiliary tables for the dropped table - if (errCode != E_OK) { - LOGE("Delete device tables for missing distributed table failed. %d", errCode); - break; - } - errCode = DeleteDistributedLogTable(tableName); + bool onceDropped = false; + errCode = IsTableOnceDropped(tableName, errCode, onceDropped); + if (errCode != E_OK) { + LOGE("query is table once dropped failed. %d", errCode); + break; + } + SQLiteUtils::ResetStatement(stmt, false, ret); + if (onceDropped) { // The table in schema was once dropped + errCode = CleanResourceForDroppedTable(tableName); if (errCode != E_OK) { - LOGE("Delete log tables for missing distributed table failed. %d", errCode); break; } missingTables.emplace_back(tableName); - } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - LOGE("Check distributed table failed. %d", errCode); - break; } - errCode = E_OK; // Check result ok for distributed table is still exists - SQLiteUtils::ResetStatement(stmt, false, errCode); } - SQLiteUtils::ResetStatement(stmt, true, errCode); + SQLiteUtils::ResetStatement(stmt, true, ret); return CheckCorruptedStatus(errCode); } @@ -1377,12 +1444,25 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const TableI return errCode; } +int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const QuerySyncObject &query) +{ + if (dbHandle_ == nullptr) { + return -E_INVALID_DB; + } + TableInfo newTable; + int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, query.GetTableName(), newTable); + if (errCode != E_OK) { + LOGE("Check new schema failed. %d", errCode); + } + return errCode; +} + int SQLiteSingleVerRelationalStorageExecutor::GetMaxTimestamp(const std::vector &tableNames, Timestamp &maxTimestamp) const { maxTimestamp = 0; for (const auto &tableName : tableNames) { - const std::string sql = "SELECT max(timestamp) from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; + const std::string sql = "SELECT MAX(timestamp) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { @@ -1506,25 +1586,19 @@ int SQLiteSingleVerRelationalStorageExecutor::GetExistsDeviceList(std::set ? and (flag & 0x04) != 0x04 and (cloud_gid != ''" - " or (cloud_gid == '' and (flag & 0x01) = 0 ));"): - ("SELECT count(rowid) from '" + DBCommon::GetLogTableName(tableName) - + "' where timestamp > ? and (flag & 0x02) = 0x02 and (cloud_gid != ''" - " or (cloud_gid == '' and (flag & 0x01) = 0 ));"); - - sqlite3_stmt *stmt = nullptr; - int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); + int errCode; + SqliteQueryHelper helper = query.GetQueryHelper(errCode); if (errCode != E_OK) { return errCode; } - errCode = SQLiteUtils::BindInt64ToStatement(stmt, 1, timestamp); + std::string tableName = query.GetRelationTableName(); + sqlite3_stmt *stmt = nullptr; + errCode = helper.GetCountRelationalCloudQueryStatement(dbHandle_, timestamp, isCloudForcePush, stmt); if (errCode != E_OK) { - SQLiteUtils::ResetStatement(stmt, true, errCode); + LOGE("failed to get count statement %d", errCode); return errCode; } errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_); @@ -1546,7 +1620,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudLogGid(const CloudSyncD return -E_INVALID_ARGS; } std::string sql = "UPDATE '" + DBCommon::GetLogTableName(cloudDataResult.tableName) - + "' SET cloud_gid = ? where data_key = ? "; + + "' SET cloud_gid = ? WHERE data_key = ? "; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { @@ -1622,6 +1696,34 @@ int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudData(CloudSyncData &cl return errCode; } +int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudGid(QuerySyncObject &query, + const SyncTimeRange &syncTimeRange, bool isCloudForcePushStrategy, std::vector &cloudGid) +{ + sqlite3_stmt *queryStmt = nullptr; + int errCode = E_OK; + SqliteQueryHelper helper = query.GetQueryHelper(errCode); + if (errCode != E_OK) { + return errCode; + } + errCode = helper.GetGidRelationalCloudQueryStatement(dbHandle_, syncTimeRange.beginTime, tableSchema_.fields, + isCloudForcePushStrategy, queryStmt); + if (errCode != E_OK) { + return errCode; + } + do { + errCode = StepNext(isMemDb_, queryStmt); + if (errCode != E_OK) { + errCode = (errCode == -E_FINISHED ? E_OK : errCode); + break; + } + GetCloudGid(queryStmt, cloudGid); + } while (errCode == E_OK); + int resetStatementErrCode = E_OK; + SQLiteUtils::ResetStatement(queryStmt, true, resetStatementErrCode); + queryStmt = nullptr; + return (errCode == E_OK ? resetStatementErrCode : errCode); +} + int SQLiteSingleVerRelationalStorageExecutor::GetCloudDataForSync(sqlite3_stmt *statement, CloudSyncData &cloudDataResult, uint32_t stepNum, uint32_t &totalSize, const uint32_t &maxSize) { @@ -1875,8 +1977,10 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogStatement(const TableSc } std::string cloudGid; + int ret = E_OK; errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); if (errCode != E_OK) { + SQLiteUtils::ResetStatement(selectStmt, true, ret); LOGE("Get cloud gid fail when bind query log statement."); return errCode; } @@ -1904,7 +2008,6 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogStatement(const TableSc index++; errCode = SQLiteUtils::BindBlobToStatement(selectStmt, index, hashValue, true); - int ret = E_OK; if (errCode != E_OK) { LOGE("Bind hash key to query log statement failed. %d", errCode); SQLiteUtils::ResetStatement(selectStmt, true, ret); @@ -1926,10 +2029,10 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogSql(const std::string & LOGE("query log table failed because of both primary key and gid are empty."); return -E_CLOUD_ERROR; } - std::string sql = "select data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key, cloud_gid FROM " + std::string sql = "SELECT data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key, cloud_gid FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log WHERE "; if (!cloudGid.empty()) { - sql += "cloud_gid = ? or "; + sql += "cloud_gid = ? OR "; } sql += "hash_key = ?"; @@ -1946,10 +2049,10 @@ int SQLiteSingleVerRelationalStorageExecutor::ExecutePutCloudData(const std::str VBucket &vBucket = downloadData.data[index]; switch (op) { case OpType::INSERT: - errCode = InsertCloudData(tableName, vBucket, tableSchema); + errCode = InsertCloudData(vBucket, tableSchema); break; case OpType::UPDATE: - errCode = UpdateCloudData(tableName, vBucket, tableSchema); + errCode = UpdateCloudData(vBucket, tableSchema); break; case OpType::DELETE: errCode = DeleteCloudData(tableName, vBucket, tableSchema); @@ -2027,8 +2130,8 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanLogs(const std::vector &pkSet, const std::string &tableName, bool queryByPk) { - std::string where = " where"; + std::string where = " WHERE"; if (!gidStr.empty()) { // gid has higher priority, because primary key may be modified - where += " rowid = (select data_key from " + DBCommon::GetLogTableName(tableName) + - " where cloud_gid = '" + gidStr + "')"; + where += " " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = (SELECT data_key FROM " + + DBCommon::GetLogTableName(tableName) + " WHERE cloud_gid = '" + gidStr + "')"; } if (!pkSet.empty() && queryByPk) { if (!gidStr.empty()) { - where += " or"; + where += " OR"; } where += " (1 = 1"; for (const auto &pk : pkSet) { - where += (" and " + pk + " = ?"); + where += (" AND " + pk + " = ?"); } where += ");"; } @@ -2456,13 +2550,13 @@ std::string SQLiteSingleVerRelationalStorageExecutor::GetWhereConditionForDataTa } int SQLiteSingleVerRelationalStorageExecutor::GetUpdateSqlForCloudSync(const TableSchema &tableSchema, - const VBucket &vBucket, const std::string &gidStr, const std::set &pkSet, std::string &updateSql) + const std::string &gidStr, const std::set &pkSet, std::string &updateSql) { if (pkSet.empty() && gidStr.empty()) { LOGE("update data fail because both primary key and gid is empty."); return -E_CLOUD_ERROR; } - std::string sql = "update " + tableSchema.name + " set"; + std::string sql = "UPDATE " + tableSchema.name + " SET"; for (const auto &field : tableSchema.fields) { sql += " " + field.colName + " = ?,"; } @@ -2472,7 +2566,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateSqlForCloudSync(const Tab return E_OK; } -static bool IsGidValid(const std::string &gidStr) +static inline bool IsGidValid(const std::string &gidStr) { if (!gidStr.empty()) { return gidStr.find("'") == std::string::npos; @@ -2496,7 +2590,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const std::set pkSet = CloudStorageUtils::GetCloudPrimaryKey(tableSchema); std::string updateSql; - errCode = GetUpdateSqlForCloudSync(tableSchema, vBucket, gidStr, pkSet, updateSql); + errCode = GetUpdateSqlForCloudSync(tableSchema, gidStr, pkSet, updateSql); if (errCode != E_OK) { return errCode; } @@ -2521,8 +2615,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const return errCode; } -int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudData(const std::string &tableName, VBucket &vBucket, - const TableSchema &tableSchema) +int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudData(VBucket &vBucket, const TableSchema &tableSchema) { CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); sqlite3_stmt *updateStmt = nullptr; @@ -2586,14 +2679,14 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateLogRecordStatement(const return errCode; } - updateLogSql += " where "; + updateLogSql += " WHERE "; if (!gidStr.empty()) { updateLogSql += "cloud_gid = '" + gidStr + "'"; } std::map pkMap = CloudStorageUtils::GetCloudPrimaryKeyFieldMap(tableSchema); if (!pkMap.empty()) { if (!gidStr.empty()) { - updateLogSql += " or "; + updateLogSql += " OR "; } updateLogSql += "(hash_key = ?);"; } @@ -2699,7 +2792,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetDeleteStatementForCloudSync(con } bool queryByPk = CloudStorageUtils::IsVbucketContainsAllPK(vBucket, pkSet); - std::string deleteSql = "delete from " + tableSchema.name; + std::string deleteSql = "DELETE FROM " + tableSchema.name; deleteSql += GetWhereConditionForDataTable(gidStr, pkSet, tableSchema.name, queryByPk); errCode = SQLiteUtils::GetStatement(dbHandle_, deleteSql, deleteStmt); if (errCode != E_OK) { @@ -2754,5 +2847,24 @@ int SQLiteSingleVerRelationalStorageExecutor::OnlyUpdateLogTable(const VBucket & { return UpdateLogRecord(vBucket, tableSchema, opType); } + +int SQLiteSingleVerRelationalStorageExecutor::DeleteMissTableTrigger(const std::string &missTable) const +{ + static const char *triggerEndName[] = { + "_ON_INSERT", + "_ON_UPDATE", + "_ON_DELETE" + }; + std::string logTableName = DBConstant::SYSTEM_TABLE_PREFIX + missTable; + for (const auto &endName : triggerEndName) { + std::string deleteSql = "DROP TRIGGER IF EXISTS " + logTableName + endName + ";"; + int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteSql); + if (errCode != E_OK) { + LOGE("[DeleteMissTableTrigger] Drop trigger failed. %d", errCode); + return errCode; + } + } + return E_OK; +} } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index 0a9c83b05fa5081d1a994b65e6ff3a1180acbe16..6c4d513c1e3c804bb1915e4ee1aa8620addec7b1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -81,6 +81,8 @@ public: int CheckQueryObjectLegal(const TableInfo &table, QueryObject &query, const std::string &schemaVersion); + int CheckQueryObjectLegal(const QuerySyncObject &query); + int GetMaxTimestamp(const std::vector &tablesName, Timestamp &maxTimestamp) const; int ExecuteQueryBySqlStmt(const std::string &sql, const std::vector &bindArgs, int packetSize, @@ -92,14 +94,17 @@ public: int GetExistsDeviceList(std::set &devices) const; - int GetUploadCount(const std::string &tableName, const Timestamp ×tamp, const bool isCloudForcePush, - int64_t &count); + int GetUploadCount(const Timestamp ×tamp, bool isCloudForcePush, + QuerySyncObject &query, int64_t &count); int UpdateCloudLogGid(const CloudSyncData &cloudDataResult); int GetSyncCloudData(CloudSyncData &cloudDataResult, const uint32_t &maxSize, SQLiteSingleVerRelationalContinueToken &token); + int GetSyncCloudGid(QuerySyncObject &query, const SyncTimeRange &syncTimeRange, bool isCloudForcePushStrategy, + std::vector &cloudGid); + void SetLocalSchema(const RelationalSchemaObject &localSchema); int GetInfoByPrimaryKeyOrGid(const TableSchema &tableSchema, const VBucket &vBucket, @@ -165,8 +170,7 @@ private: void SetTableInfo(const TableInfo &tableInfo); // When put or get sync data, must call the func first. - int GeneLogInfoForExistedData(sqlite3 *db, const std::string &tableName, const TableInfo &table, - const std::string &calPrimaryKeyHash); + int GeneLogInfoForExistedData(sqlite3 *db, const std::string &tableName, const std::string &calPrimaryKeyHash); int GetCloudDataForSync(sqlite3_stmt *statement, CloudSyncData &cloudDataResult, uint32_t stepNum, uint32_t &totalSize, const uint32_t &maxSize); @@ -201,7 +205,7 @@ private: int GetInfoByStatement(sqlite3_stmt *statement, std::vector &assetFields, const std::map &pkMap, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo); - int InsertCloudData(const std::string &tableName, VBucket &vBucket, const TableSchema &tableSchema); + int InsertCloudData(VBucket &vBucket, const TableSchema &tableSchema); int InsertLogRecord(const TableSchema &tableSchema, VBucket &vBucket); @@ -217,12 +221,12 @@ private: std::string GetWhereConditionForDataTable(const std::string &gidStr, const std::set &pkSet, const std::string &tableName, bool queryByPk = true); - int GetUpdateSqlForCloudSync(const TableSchema &tableSchema, const VBucket &vBucket, const std::string &gidStr, + int GetUpdateSqlForCloudSync(const TableSchema &tableSchema, const std::string &gidStr, const std::set &pkSet, std::string &updateSql); int GetUpdateDataTableStatement(const VBucket &vBucket, const TableSchema &tableSchema, sqlite3_stmt *&updateStmt); - int UpdateCloudData(const std::string &tableName, VBucket &vBucket, const TableSchema &tableSchema); + int UpdateCloudData(VBucket &vBucket, const TableSchema &tableSchema); int GetUpdateLogRecordStatement(const TableSchema &tableSchema, const VBucket &vBucket, OpType opType, std::vector &updateColName, sqlite3_stmt *&updateLogStmt); @@ -241,6 +245,12 @@ private: bool IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize); + int DeleteMissTableTrigger(const std::string &missTable) const; + + int CleanResourceForDroppedTable(const std::string &tableName); + + int IsTableOnceDropped(const std::string &tableName, int execCode, bool &onceDropped); + std::string baseTblName_; TableInfo table_; // Always operating table, user table when get, device table when put. TableSchema tableSchema_; // for cloud table diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp index 92d592b01c8edb97293cd483424df1a6e7381f53..4c974a69542d96aa2627622ca44b440e320d286a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp @@ -49,7 +49,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryInfoSql(const std::string sql += ", b." + pk; } sql += " from '" + DBCommon::GetLogTableName(tableName) + "' AS a LEFT JOIN '" + tableName + "' AS b "; - sql += " ON (a.data_key = b.rowid) WHERE "; + sql += " ON (a.data_key = b." + std::string(DBConstant::SQLITE_INNER_ROWID) + ") WHERE "; if (!gid.empty()) { sql += " a.cloud_gid = ? or "; } @@ -66,7 +66,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetFillDownloadAssetStatement(cons sql += field.colName + " = ?,"; } sql.pop_back(); - sql += " WHERE rowid = ("; + sql += " WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = ("; sql += "SELECT data_key FROM " + DBCommon::GetLogTableName(tableName) + " where cloud_gid = ?);"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); @@ -94,7 +94,6 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForDownload(const Ta LOGE("Miss gid when fill Asset"); return errCode; } - sqlite3_stmt *stmt = nullptr; std::vector assetsField; errCode = CloudStorageUtils::GetAssetFieldsFromSchema(tableSchema, vBucket, assetsField); if (errCode != E_OK) { @@ -109,6 +108,7 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForDownload(const Ta } else { CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetAfterDownloadFail); } + sqlite3_stmt *stmt = nullptr; errCode = GetFillDownloadAssetStatement(tableSchema.name, vBucket, assetsField, stmt); if (errCode != E_OK) { return errCode; @@ -187,8 +187,8 @@ int SQLiteSingleVerRelationalStorageExecutor::InitFillUploadAssetStatement(const sql += item.first + " = ?,"; } sql.pop_back(); - sql += " WHERE rowid = ? and (select 1 from " + DBCommon::GetLogTableName(tableName) + - " WHERE timestamp = ?);"; + sql += " WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = ? and (select 1 from " + + DBCommon::GetLogTableName(tableName) + " WHERE timestamp = ?);"; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); if (errCode != E_OK) { return errCode; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp index 5d601eb38ff29576780260f5b6057b7aa6f4d063..85f32838b907300bf372560cc9751f088fec1172 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp @@ -426,8 +426,9 @@ int SQLiteUtils::ExecuteRawSQL(sqlite3 *db, const std::string &sql) } } while (true); - SQLiteUtils::ResetStatement(stmt, true, errCode); - return errCode; + int ret = E_OK; + SQLiteUtils::ResetStatement(stmt, true, ret); + return errCode != E_OK ? errCode : ret; } int SQLiteUtils::SetKey(sqlite3 *db, CipherType type, const CipherPassword &passwd, bool setWal, uint32_t iterTimes) @@ -815,7 +816,7 @@ int SetFieldInfo(sqlite3_stmt *statement, TableInfo &table) std::string tmpString; (void) SQLiteUtils::GetColumnTextValue(statement, 1, tmpString); // 1 means column name index - if (!DBCommon::CheckIsAlnumAndUnderscore(tmpString)) { + if (!DBCommon::CheckIsAlnumOrUnderscore(tmpString)) { LOGE("[AnalysisSchema] unsupported field name."); return -E_NOT_SUPPORT; } @@ -881,7 +882,7 @@ int SQLiteUtils::AnalysisSchema(sqlite3 *db, const std::string &tableName, Table return -E_INVALID_DB; } - if (!DBCommon::CheckIsAlnumAndUnderscore(tableName)) { + if (!DBCommon::CheckIsAlnumOrUnderscore(tableName)) { LOGE("[AnalysisSchema] unsupported table name."); return -E_NOT_SUPPORT; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp index 55f8f506ed0f4b5806093b95023e702414fcda5d..e4d390758b2f66d4f0661ceea3abbc6e1d7d417e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp @@ -145,7 +145,23 @@ int StorageProxy::GetUploadCount(const std::string &tableName, const Timestamp & LOGE("the transaction has not been started"); return -E_TRANSACT_STATE; } - return store_->GetUploadCount(tableName, localMark, isCloudForcePush, count); + QuerySyncObject query; + query.SetTableName(tableName); + return store_->GetUploadCount(query, localMark, isCloudForcePush, count); +} + +int StorageProxy::GetUploadCount(const QuerySyncObject &query, const Timestamp &localMark, + bool isCloudForcePush, int64_t &count) +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return -E_INVALID_DB; + } + if (!transactionExeFlag_.load()) { + LOGE("the transaction has not been started"); + return -E_TRANSACT_STATE; + } + return store_->GetUploadCount(query, localMark, isCloudForcePush, count); } int StorageProxy::FillCloudGid(const CloudSyncData &data) @@ -163,6 +179,14 @@ int StorageProxy::FillCloudGid(const CloudSyncData &data) int StorageProxy::GetCloudData(const std::string &tableName, const Timestamp &timeRange, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) +{ + QuerySyncObject querySyncObject; + querySyncObject.SetTableName(tableName); + return GetCloudData(querySyncObject, timeRange, continueStmtToken, cloudDataResult); +} + +int StorageProxy::GetCloudData(const QuerySyncObject &querySyncObject, const Timestamp &timeRange, + ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { std::shared_lock readLock(storeMutex_); if (store_ == nullptr) { @@ -173,11 +197,11 @@ int StorageProxy::GetCloudData(const std::string &tableName, const Timestamp &ti return -E_TRANSACT_STATE; } TableSchema tableSchema; - int errCode = store_->GetCloudTableSchema(tableName, tableSchema); + int errCode = store_->GetCloudTableSchema(querySyncObject.GetRelationTableName(), tableSchema); if (errCode != E_OK) { return errCode; } - return store_->GetCloudData(tableSchema, timeRange, continueStmtToken, cloudDataResult); + return store_->GetCloudData(tableSchema, querySyncObject, timeRange, continueStmtToken, cloudDataResult); } int StorageProxy::GetCloudDataNext(ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) const @@ -193,6 +217,21 @@ int StorageProxy::GetCloudDataNext(ContinueToken &continueStmtToken, CloudSyncDa return store_->GetCloudDataNext(continueStmtToken, cloudDataResult); } +int StorageProxy::GetCloudGid(const QuerySyncObject &querySyncObject, bool isCloudForcePush, + std::vector &cloudGid) +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return -E_INVALID_DB; + } + TableSchema tableSchema; + int errCode = store_->GetCloudTableSchema(querySyncObject.GetRelationTableName(), tableSchema); + if (errCode != E_OK) { + return errCode; + } + return store_->GetCloudGid(tableSchema, querySyncObject, isCloudForcePush, cloudGid); +} + int StorageProxy::GetInfoByPrimaryKeyOrGid(const std::string &tableName, const VBucket &vBucket, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo) { @@ -306,7 +345,7 @@ int StorageProxy::GetPrimaryColNamesWithAssetsFields(const TableName &tableName, return E_OK; } -int StorageProxy::NotifyChangedData(const std::string deviceName, ChangedData &&changedData) +int StorageProxy::NotifyChangedData(const std::string &deviceName, ChangedData &&changedData) { std::shared_lock readLock(storeMutex_); if (store_ == nullptr) { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp index ea2324cc23eef6506ef5f3e3f539b5e566e82425..de16c00c787cd859b0bc35249cf1d902a9979dea 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp @@ -282,22 +282,15 @@ void CloudDBProxy::InnerActionTask(const std::shared_ptr &co status = DMLActionTask(context, cloudDb, action); break; case QUERY: { - VBucket queryExtend; - std::vector data; - context->MoveOutQueryExtendAndData(queryExtend, data); - status = cloudDb->Query(context->GetTableName(), queryExtend, data); - context->MoveInQueryExtendAndData(queryExtend, data); - + status = QueryAction(context, cloudDb); if (status == QUERY_END) { setResAlready = true; - context->SetActionRes(-E_QUERY_END); } break; } - case LOCK: { + case LOCK: status = InnerActionLock(context, cloudDb); break; - } case UNLOCK: status = cloudDb->UnLock(); break; @@ -314,11 +307,7 @@ void CloudDBProxy::InnerActionTask(const std::shared_ptr &co } context->FinishAndNotify(); - { - std::lock_guard uniqueLock(asyncTaskMutex_); - asyncTaskCount_--; - } - asyncTaskCv_.notify_all(); + DecAsyncTaskCount(); } DBStatus CloudDBProxy::InnerActionLock(const std::shared_ptr &context, @@ -358,6 +347,29 @@ int CloudDBProxy::GetInnerErrorCode(DBStatus status) } } +DBStatus CloudDBProxy::QueryAction(const std::shared_ptr &context, + const std::shared_ptr &cloudDb) +{ + VBucket queryExtend; + std::vector data; + context->MoveOutQueryExtendAndData(queryExtend, data); + DBStatus status = cloudDb->Query(context->GetTableName(), queryExtend, data); + context->MoveInQueryExtendAndData(queryExtend, data); + if (status == QUERY_END) { + context->SetActionRes(-E_QUERY_END); + } + return status; +} + +void CloudDBProxy::DecAsyncTaskCount() +{ + { + std::lock_guard uniqueLock(asyncTaskMutex_); + asyncTaskCount_--; + } + asyncTaskCv_.notify_all(); +} + CloudDBProxy::CloudActionContext::CloudActionContext() : actionFinished_(false), actionRes_(OK), @@ -460,8 +472,8 @@ Info CloudDBProxy::CloudActionContext::GetInfo() return info; } -void CloudDBProxy::CloudActionContext::SetInfo(const uint32_t &totalCount, - const uint32_t &successCount, const uint32_t &failedCount) +void CloudDBProxy::CloudActionContext::SetInfo(uint32_t totalCount, + uint32_t successCount, uint32_t failedCount) { totalCount_ = totalCount; successCount_ = successCount; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h index da1eaee5b7e7ffb5ee46845ad207685fba645783..b4eefc1289653c1d34855e4042b249538d6684a0 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h @@ -88,7 +88,7 @@ protected: Info GetInfo(); - void SetInfo(const uint32_t &totalCount, const uint32_t &successCount, const uint32_t &failedCount); + void SetInfo(uint32_t totalCount, uint32_t successCount, uint32_t failedCount); void SetTableName(const std::string &tableName); @@ -134,6 +134,11 @@ protected: static int GetInnerErrorCode(DBStatus status); + static DBStatus QueryAction(const std::shared_ptr &context, + const std::shared_ptr &cloudDb); + + void DecAsyncTaskCount(); + mutable std::shared_mutex cloudMutex_; mutable std::shared_mutex assetLoaderMutex_; std::shared_ptr iCloudDb_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp index 6e3b8f4ca3d17316ce7375002284ed74c02ae7a6..b5333e511bb908bdaf6291eadcb5eeba7343ca3a 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp @@ -16,7 +16,7 @@ namespace DistributedDB { -OpType CloudForcePullStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudForcePullStrategy::TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) { if (existInLocal) { if (!IsDelete(localInfo) && IsDelete(cloudInfo)) { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h index 79db2efdd415f7da556d84f42eea78baf46889bd..66f5fcd2128835e1a15d31ebb1c610eef2a1939e 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h @@ -19,7 +19,7 @@ namespace DistributedDB { class CloudForcePullStrategy : public CloudSyncStrategy { public: - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) override; bool JudgeUpdateCursor() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp index ed2f8e4eb63001690e5d03afda99a0217868495b..b7b78186347937b61c895ce06caa710effe01181 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp @@ -16,7 +16,7 @@ namespace DistributedDB { const std::string cloud_device_name = "cloud"; -OpType CloudForcePushStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudForcePushStrategy::TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) { bool isCloudDelete = IsDelete(cloudInfo); if (!existInLocal) { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h index b7616e67e5c3fe6f7147a4ebe1c9968958c3adaa..8543d3f9a3dc95b5a815aee5fe68666eb5680e6d 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h @@ -19,7 +19,7 @@ namespace DistributedDB { class CloudForcePushStrategy : public CloudSyncStrategy { public: - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) override; bool JudgeUpdateCursor() override; diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_trace.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.cpp similarity index 50% rename from relational_store/frameworks/native/rdb/mock/include/rdb_trace.h rename to kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.cpp index 660ad1daf770805642cf465c69198554e04dba5e..50346ccaf1ce45f9945af100065087e7870a885d 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_trace.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.cpp @@ -1,27 +1,38 @@ -/* - * Copyright (c) 2022 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 NATIVE_RDB_RDB_TRACE_H -#define NATIVE_RDB_RDB_TRACE_H - -#define DO_NOTHING - -#ifdef RDB_TRACE_ON -#include "hitrace.h" -#define DISTRIBUTED_DATA_HITRACE(trace) HiTrace hitrace(trace) -#else -#define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING -#endif - -#endif \ No newline at end of file +/* + * 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 "cloud_locker.h" + +#include "db_errno.h" +namespace DistributedDB { +int CloudLocker::BuildCloudLock(const AfterBuildAction &buildAction, const BeforeFinalize &finalize, + std::shared_ptr &locker) +{ + locker = std::make_shared(); + int errCode = buildAction(); + if (errCode != E_OK) { + locker = nullptr; + } else { + locker->finalize_ = finalize; + } + return errCode; +} + +CloudLocker::~CloudLocker() +{ + if (finalize_) { + finalize_(); + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_errno.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.h similarity index 51% rename from relational_store/frameworks/native/rdb/mock/include/sqlite_errno.h rename to kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.h index b1428f80b7d069e16c21183344a2ae1f57ca56f3..979a55ff5b97152ce7e1fca52096ec224d9f5729 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_errno.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_locker.h @@ -1,33 +1,33 @@ -/* - * Copyright (c) 2021 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 NATIVE_RDB_SQLITE_ERRNO_H -#define NATIVE_RDB_SQLITE_ERRNO_H - -namespace OHOS { -namespace NativeRdb { - -class SQLiteError { -public: - static int ErrNo(int sqliteErr) - { - return -sqliteErr; - } -}; - -} // namespace NativeRdb -} // namespace OHOS - -#endif +/* + * 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 CLOUD_LOCKER_H +#define CLOUD_LOCKER_H +#include +#include "icloud_syncer.h" +namespace DistributedDB { +using AfterBuildAction = std::function; +using BeforeFinalize = std::function; +class CloudLocker final { +public: + static int BuildCloudLock(const AfterBuildAction &buildAction, const BeforeFinalize &finalize, + std::shared_ptr &locker); + CloudLocker() = default; + ~CloudLocker(); +private: + BeforeFinalize finalize_; +}; +} +#endif // CLOUD_LOCKER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp index 00d6fccdd9690a9f9505b64f954a19ee707dc443..d7c368dafe5aa925f6e8830dc13a06d42000465f 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp @@ -16,7 +16,7 @@ namespace DistributedDB { -OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) { bool isCloudDelete = IsDelete(cloudInfo); bool isLocalDelete = IsDelete(localInfo); @@ -30,26 +30,25 @@ OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localIn OpType type = OpType::NOT_HANDLE; if (localInfo.timestamp > cloudInfo.timestamp) { if (localInfo.cloudGid.empty()) { - type = isCloudDelete ? OpType::NOT_HANDLE : OpType::ONLY_UPDATE_GID; + type = isCloudDelete ? OpType::NOT_HANDLE : (isLocalDelete ? OpType::INSERT : OpType::ONLY_UPDATE_GID); } else { type = isCloudDelete ? OpType::CLEAR_GID : type; } return type; } if (isCloudDelete) { - if (isLocalDelete) { - return OpType::UPDATE_TIMESTAMP; - } else { - return OpType::DELETE; - } - } else { - if (isLocalDelete) { - type = OpType::INSERT; - } else { - type = OpType::UPDATE; - } + return isLocalDelete ? OpType::UPDATE_TIMESTAMP : OpType::DELETE; + } + if (isLocalDelete) { + return OpType::INSERT; + } + // avoid local data insert to cloud success but return failed + // we just fill back gid here + if ((localInfo.timestamp == cloudInfo.timestamp) && + (localInfo.wTimestamp == cloudInfo.wTimestamp) && localInfo.cloudGid.empty()) { + return OpType::ONLY_UPDATE_GID; } - return type; + return OpType::UPDATE; } bool CloudMergeStrategy::JudgeUpdateCursor() diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h index 2f07eb5bb76002d1c267ae5b917cadb35620724b..7b752e5375af8b82ac2f1f19fb53f9147208602c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h @@ -23,7 +23,7 @@ public: CloudMergeStrategy() = default; ~CloudMergeStrategy() override = default; - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) override; bool JudgeUpdateCursor() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h index 2d0fd48b0459d75d071ccb97a2aa15d35d4e3c72..169c519a2b5d1dea49d1de40ce73aa403ed9009b 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h @@ -27,7 +27,7 @@ public: CloudSyncStrategy() = default; virtual ~CloudSyncStrategy() = default; - virtual OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) + virtual OpType TagSyncDataStatus(bool existInLocal, const LogInfo &localInfo, const LogInfo &cloudInfo) { (void)existInLocal; (void)localInfo; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp index 385f150d649cae971551080efacadcdcab30cb36..4e80f0e5801501ae6270c6e39b2ae9e50af7d0bf 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp @@ -122,7 +122,7 @@ Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, VBucke coveredAssetsIndexMap.erase(it); if (errCode != E_OK) { LOGE("Tag assets UPDATE or NO_CHANGE fail!"); - break; + return {}; } } for (const auto &noHandledAssetKvPair : coveredAssetsIndexMap) { @@ -130,7 +130,7 @@ Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, VBucke covered[noHandledAssetKvPair.second], res, errCode); if (errCode != E_OK) { LOGE("Tag assets INSERT fail!"); - break; + return {}; } } return res; @@ -183,7 +183,7 @@ Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, VBucket if (covered.hash != beCovered.hash) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::UPDATE, covered, res, errCode); } else { - Assets tmpAssets; + Assets tmpAssets = {}; TagAssetWithNormalStatus(true, AssetOpType::NO_CHANGE, covered, tmpAssets, errCode); } return res; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp index ce805f86368949d71f04e54395741b9926b34c61..d30854572001e00bb3ba0b7738a61a4b00957196 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp @@ -18,8 +18,7 @@ #include "cloud/cloud_sync_utils.h" namespace DistributedDB { - -int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, +int CloudSyncUtils::GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, std::vector &cloudPkVals) { if (!cloudPkVals.empty()) { @@ -27,10 +26,10 @@ int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNa return -E_INVALID_ARGS; } for (const auto &pkColName : pkColNames) { - // if data is primary key or is a composite primary key, then use rowID as value + // If data is primary key or is a composite primary key, then use rowID as value // The single primary key table, does not contain rowid. if (pkColName == CloudDbConstant::ROW_ID_FIELD_NAME) { - cloudPkVals.push_back(dataKey); + cloudPkVals.emplace_back(dataKey); continue; } auto iter = datum.find(pkColName); @@ -43,7 +42,7 @@ int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNa return E_OK; } -ChangeType OpTypeToChangeType(OpType strategy) +ChangeType CloudSyncUtils::OpTypeToChangeType(OpType strategy) { switch (strategy) { case OpType::INSERT: @@ -57,12 +56,12 @@ ChangeType OpTypeToChangeType(OpType strategy) } } -bool IsSinglePrimaryKey(const std::vector &pkColNames) +bool CloudSyncUtils::IsSinglePrimaryKey(const std::vector &pkColNames) { return pkColNames.size() == 1 && pkColNames[0] != CloudDbConstant::ROW_ID_FIELD_NAME; } -void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames) +void CloudSyncUtils::RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames) { for (auto item = datum.begin(); item != datum.end();) { const auto &key = item->first; @@ -79,7 +78,7 @@ void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector & } } -AssetOpType StatusToFlag(AssetStatus status) +AssetOpType CloudSyncUtils::StatusToFlag(AssetStatus status) { switch (status) { case AssetStatus::INSERT: @@ -97,20 +96,20 @@ AssetOpType StatusToFlag(AssetStatus status) } } -void StatusToFlagForAsset(Asset &asset) +void CloudSyncUtils::StatusToFlagForAsset(Asset &asset) { asset.flag = static_cast(StatusToFlag(static_cast(asset.status))); asset.status = static_cast(AssetStatus::NORMAL); } -void StatusToFlagForAssets(Assets &assets) +void CloudSyncUtils::StatusToFlagForAssets(Assets &assets) { for (Asset &asset : assets) { StatusToFlagForAsset(asset); } } -void StatusToFlagForAssetsInRecord(const std::vector &fields, VBucket &record) +void CloudSyncUtils::StatusToFlagForAssetsInRecord(const std::vector &fields, VBucket &record) { for (const Field &field : fields) { if (field.type == TYPE_INDEX && record[field.colName].index() == TYPE_INDEX) { @@ -121,22 +120,22 @@ void StatusToFlagForAssetsInRecord(const std::vector &fields, VBucket &re } } -bool IsChngDataEmpty(const ChangedData &changedData) +bool CloudSyncUtils::IsChangeDataEmpty(const ChangedData &changedData) { return changedData.primaryData[ChangeType::OP_INSERT].empty() || changedData.primaryData[ChangeType::OP_UPDATE].empty() || changedData.primaryData[ChangeType::OP_DELETE].empty(); } -bool EqualInMsLevel(const Timestamp cmp, const Timestamp beCmp) +bool CloudSyncUtils::EqualInMsLevel(const Timestamp cmp, const Timestamp beCmp) { - return cmp / CloudDbConstant::TEN_THOUSAND == beCmp / CloudDbConstant::TEN_THOUSAND; + return (cmp / CloudDbConstant::TEN_THOUSAND) == (beCmp / CloudDbConstant::TEN_THOUSAND); } -bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo) +bool CloudSyncUtils::NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo) { - // if timeStamp, write timestamp, cloudGid are all the same, - // we thought that the datum is mostly be the same between cloud and local + // If timeStamp, write timestamp, cloudGid are all the same, + // We thought that the datum is mostly be the same between cloud and local // However, there are still slightly possibility that it may be created from different device, // So, during the strategy policy [i.e. TagSyncDataStatus], the datum was tagged as UPDATE // But we won't notify the datum @@ -145,4 +144,288 @@ bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo) localLogInfo.cloudGid == cloudLogInfo.cloudGid; return !isSame; } + +int CloudSyncUtils::CheckParamValid(const std::vector &devices, SyncMode mode) +{ + if (devices.size() != 1) { + LOGE("[CloudSyncer] invalid devices size %zu", devices.size()); + return -E_INVALID_ARGS; + } + for (const auto &dev: devices) { + if (dev.empty() || dev.size() > DBConstant::MAX_DEV_LENGTH) { + LOGE("[CloudSyncer] invalid device, size %zu", dev.size()); + return -E_INVALID_ARGS; + } + } + if (mode >= SyncMode::SYNC_MODE_PUSH_ONLY && mode < SyncMode::SYNC_MODE_CLOUD_MERGE) { + LOGE("[CloudSyncer] not support mode %d", static_cast(mode)); + return -E_NOT_SUPPORT; + } + if (mode < SyncMode::SYNC_MODE_PUSH_ONLY || mode > SyncMode::SYNC_MODE_CLOUD_FORCE_PULL) { + LOGE("[CloudSyncer] invalid mode %d", static_cast(mode)); + return -E_INVALID_ARGS; + } + return E_OK; +} + +LogInfo CloudSyncUtils::GetCloudLogInfo(DistributedDB::VBucket &datum) +{ + LogInfo cloudLogInfo; + cloudLogInfo.dataKey = 0; + cloudLogInfo.timestamp = (Timestamp)std::get(datum[CloudDbConstant::MODIFY_FIELD]); + cloudLogInfo.wTimestamp = (Timestamp)std::get(datum[CloudDbConstant::CREATE_FIELD]); + cloudLogInfo.flag = (std::get(datum[CloudDbConstant::DELETE_FIELD])) ? 1u : 0u; + cloudLogInfo.cloudGid = std::get(datum[CloudDbConstant::GID_FIELD]); + return cloudLogInfo; +} + +int CloudSyncUtils::SaveChangedDataByType(const VBucket &datum, ChangedData &changedData, + const DataInfoWithLog &localInfo, ChangeType type) +{ + int ret = E_OK; + std::vector cloudPkVals; + if (type == ChangeType::OP_DELETE) { + ret = CloudSyncUtils::GetCloudPkVals(localInfo.primaryKeys, changedData.field, localInfo.logInfo.dataKey, + cloudPkVals); + } else { + ret = CloudSyncUtils::GetCloudPkVals(datum, changedData.field, localInfo.logInfo.dataKey, cloudPkVals); + } + if (ret != E_OK) { + return ret; + } + changedData.primaryData[type].emplace_back(std::move(cloudPkVals)); + return E_OK; +} + +int CloudSyncUtils::FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, + size_t &delIdx) +{ + for (std::pair pair : deletedList) { + if (pair.first == hashKey) { + delIdx = pair.second; + return E_OK; + } + } + return -E_INTERNAL_ERROR; +} + +int CloudSyncUtils::CheckCloudSyncDataValid(const CloudSyncData &uploadData, const std::string &tableName, + const int64_t &count, uint64_t &taskId) +{ + size_t insRecordLen = uploadData.insData.record.size(); + size_t insExtendLen = uploadData.insData.extend.size(); + size_t updRecordLen = uploadData.updData.record.size(); + size_t updExtendLen = uploadData.updData.extend.size(); + size_t delRecordLen = uploadData.delData.record.size(); + size_t delExtendLen = uploadData.delData.extend.size(); + + bool syncDataValid = (uploadData.tableName == tableName) && + ((insRecordLen > 0 && insExtendLen > 0 && insRecordLen == insExtendLen) || + (updRecordLen > 0 && updExtendLen > 0 && updRecordLen == updExtendLen) || + (delRecordLen > 0 && delExtendLen > 0 && delRecordLen == delExtendLen)); + if (!syncDataValid) { + LOGE("[CloudSyncUtils] upload data is empty but upload count is not zero or upload table name" + " is not the same as table name of sync data."); + return -E_INTERNAL_ERROR; + } + int64_t syncDataCount = static_cast(insRecordLen) + static_cast(updRecordLen) + + static_cast(delRecordLen); + if (syncDataCount > count) { + LOGE("[CloudSyncUtils] Size of a batch of sync data is greater than upload data size. count %d", count); + return -E_INTERNAL_ERROR; + } + return E_OK; +} + +void CloudSyncUtils::ClearCloudSyncData(CloudSyncData &uploadData) +{ + std::vector().swap(uploadData.insData.record); + std::vector().swap(uploadData.insData.extend); + std::vector().swap(uploadData.insData.rowid); + std::vector().swap(uploadData.updData.record); + std::vector().swap(uploadData.updData.extend); + std::vector().swap(uploadData.delData.record); + std::vector().swap(uploadData.delData.extend); +} + +int CloudSyncUtils::GetWaterMarkAndUpdateTime(std::vector &extend, Timestamp &waterMark) +{ + for (auto &extendData: extend) { + if (extendData.empty() || extendData.find(CloudDbConstant::MODIFY_FIELD) == extendData.end()) { + LOGE("[CloudSyncer] VBucket is empty or MODIFY_FIELD doesn't exist."); + return -E_INTERNAL_ERROR; + } + if (TYPE_INDEX != extendData.at(CloudDbConstant::MODIFY_FIELD).index()) { + LOGE("[CloudSyncer] VBucket's MODIFY_FIELD doestn't fit int64_t."); + return -E_INTERNAL_ERROR; + } + if (extendData.empty() || extendData.find(CloudDbConstant::CREATE_FIELD) == extendData.end()) { + LOGE("[CloudSyncer] VBucket is empty or CREATE_FIELD doesn't exist."); + return -E_INTERNAL_ERROR; + } + if (TYPE_INDEX != extendData.at(CloudDbConstant::CREATE_FIELD).index()) { + LOGE("[CloudSyncer] VBucket's CREATE_FIELD doestn't fit int64_t."); + return -E_INTERNAL_ERROR; + } + waterMark = std::max(int64_t(waterMark), std::get(extendData.at(CloudDbConstant::MODIFY_FIELD))); + int64_t modifyTime = + std::get(extendData.at(CloudDbConstant::MODIFY_FIELD)) / CloudDbConstant::TEN_THOUSAND; + int64_t createTime = + std::get(extendData.at(CloudDbConstant::CREATE_FIELD)) / CloudDbConstant::TEN_THOUSAND; + extendData.insert_or_assign(CloudDbConstant::MODIFY_FIELD, modifyTime); + extendData.insert_or_assign(CloudDbConstant::CREATE_FIELD, createTime); + } + return E_OK; +} + +bool CloudSyncUtils::CheckCloudSyncDataEmpty(const CloudSyncData &uploadData) +{ + return uploadData.insData.extend.empty() && uploadData.insData.record.empty() && + uploadData.updData.extend.empty() && uploadData.updData.record.empty() && + uploadData.delData.extend.empty() && uploadData.delData.record.empty(); +} + +void CloudSyncUtils::ModifyCloudDataTime(DistributedDB::VBucket &data) +{ + // data already check field modify_field and create_field + int64_t modifyTime = std::get(data[CloudDbConstant::MODIFY_FIELD]) * CloudDbConstant::TEN_THOUSAND; + int64_t createTime = std::get(data[CloudDbConstant::CREATE_FIELD]) * CloudDbConstant::TEN_THOUSAND; + data[CloudDbConstant::MODIFY_FIELD] = modifyTime; + data[CloudDbConstant::CREATE_FIELD] = createTime; +} + +// After doing a batch upload, we need to use CloudSyncData's maximum timestamp to update the water mark; +int CloudSyncUtils::UpdateExtendTime(CloudSyncData &uploadData, const int64_t &count, uint64_t taskId, + Timestamp &waterMark) +{ + int ret = CloudSyncUtils::CheckCloudSyncDataValid(uploadData, uploadData.tableName, count, taskId); + if (ret != E_OK) { + LOGE("[CloudSyncer] Invalid Sync Data when get local water mark."); + return ret; + } + if (!uploadData.insData.extend.empty()) { + if (uploadData.insData.record.size() != uploadData.insData.extend.size()) { + LOGE("[CloudSyncer] Inconsistent size of inserted data."); + return -E_INTERNAL_ERROR; + } + ret = CloudSyncUtils::GetWaterMarkAndUpdateTime(uploadData.insData.extend, waterMark); + if (ret != E_OK) { + return ret; + } + } + + if (!uploadData.updData.extend.empty()) { + if (uploadData.updData.record.size() != uploadData.updData.extend.size()) { + LOGE("[CloudSyncer] Inconsistent size of updated data, %d.", -E_INTERNAL_ERROR); + return -E_INTERNAL_ERROR; + } + ret = CloudSyncUtils::GetWaterMarkAndUpdateTime(uploadData.updData.extend, waterMark); + if (ret != E_OK) { + return ret; + } + } + + if (!uploadData.delData.extend.empty()) { + if (uploadData.delData.record.size() != uploadData.delData.extend.size()) { + LOGE("[CloudSyncer] Inconsistent size of deleted data, %d.", -E_INTERNAL_ERROR); + return -E_INTERNAL_ERROR; + } + ret = CloudSyncUtils::GetWaterMarkAndUpdateTime(uploadData.delData.extend, waterMark); + if (ret != E_OK) { + return ret; + } + } + return E_OK; +} + +void CloudSyncUtils::UpdateLocalCache(OpType opType, const LogInfo &cloudInfo, const LogInfo &localInfo, + std::map &localLogInfoCache) +{ + // only cloud delete data need records + if ((cloudInfo.flag & 0x01) != 1) { + return; + } + LogInfo updateLogInfo; + std::string hashKey(localInfo.hashKey.begin(), localInfo.hashKey.end()); + switch (opType) { + case OpType::DELETE: { + updateLogInfo.flag |= 0x01; + updateLogInfo.timestamp = cloudInfo.timestamp; + updateLogInfo.wTimestamp = cloudInfo.wTimestamp; + updateLogInfo.device = "cloud"; + localLogInfoCache[hashKey] = updateLogInfo; + break; + } + case OpType::CLEAR_GID: + case OpType::UPDATE_TIMESTAMP: { + updateLogInfo = localInfo; + updateLogInfo.cloudGid.clear(); + localLogInfoCache[hashKey] = updateLogInfo; + break; + } + default: + break; + } +} + +int CloudSyncUtils::SaveChangedData(ICloudSyncer::SyncParam ¶m, size_t dataIndex, + const ICloudSyncer::DataInfo &dataInfo, std::vector> &deletedList) +{ + OpType opType = param.downloadData.opType[dataIndex]; + Key hashKey = dataInfo.localInfo.logInfo.hashKey; + if (param.deletePrimaryKeySet.find(hashKey) != param.deletePrimaryKeySet.end()) { + if (opType == OpType::INSERT) { + size_t delIdx; + int errCode = CloudSyncUtils::FindDeletedListIndex(deletedList, hashKey, delIdx); + if (errCode != E_OK) { + LOGE("[CloudSyncer] FindDeletedListIndex could not find delete item."); + return errCode; + } + param.changedData.primaryData[ChangeType::OP_DELETE].erase( + param.changedData.primaryData[ChangeType::OP_DELETE].begin() + delIdx); + (void)param.dupHashKeySet.insert(hashKey); + opType = OpType::UPDATE; + // only composite primary key needs to be processed. + if (!param.isSinglePrimaryKey) { + param.withoutRowIdData.updateData.emplace_back(dataIndex, + param.changedData.primaryData[ChangeType::OP_UPDATE].size()); + } + } else if (opType == OpType::DELETE) { + std::pair pair{hashKey, static_cast( + param.changedData.primaryData[ChangeType::OP_DELETE].size())}; + deletedList.emplace_back(pair); + } else { + LOGW("[CloudSyncer] deletePrimaryKeySet ignore opType %d.", opType); + } + } + // INSERT: for no primary key or composite primary key situation + if (!param.isSinglePrimaryKey && opType == OpType::INSERT) { + param.withoutRowIdData.insertData.push_back(dataIndex); + return E_OK; + } + switch (opType) { + // INSERT: only for single primary key situation + case OpType::INSERT: + return CloudSyncUtils::SaveChangedDataByType( + param.downloadData.data[dataIndex], param.changedData, dataInfo.localInfo, ChangeType::OP_INSERT); + case OpType::UPDATE: + if (CloudSyncUtils::NeedSaveData(dataInfo.localInfo.logInfo, dataInfo.cloudLogInfo)) { + return CloudSyncUtils::SaveChangedDataByType(param.downloadData.data[dataIndex], param.changedData, + dataInfo.localInfo, ChangeType::OP_UPDATE); + } + return E_OK; + case OpType::DELETE: + return CloudSyncUtils::SaveChangedDataByType(param.downloadData.data[dataIndex], param.changedData, + dataInfo.localInfo, ChangeType::OP_DELETE); + default: + return E_OK; + } +} + +void CloudSyncUtils::ClearWithoutData(ICloudSyncer::SyncParam ¶m) +{ + param.withoutRowIdData.insertData.clear(); + param.withoutRowIdData.updateData.clear(); + param.withoutRowIdData.assetInsertData.clear(); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h index a601cc586da789004bdd1f24a9c10455cd7d354c..a78dea6ca8658e5230cf7ca1407a4de2ea28c71c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h @@ -16,39 +16,75 @@ #define CLOUD_SYNC_UTILS_H #include +#include #include "cloud/cloud_store_types.h" +#include "icloud_syncer.h" #include "icloud_sync_storage_interface.h" namespace DistributedDB { +class CloudSyncUtils { +public: + static constexpr const int GID_INDEX = 0; + static constexpr const int PREFIX_INDEX = 1; + static constexpr const int STRATEGY_INDEX = 2; + static constexpr const int ASSETS_INDEX = 3; + static constexpr const int HASH_KEY_INDEX = 4; + static constexpr const int PRIMARY_KEY_INDEX = 5; -constexpr int GID_INDEX = 0; -constexpr int PREFIX_INDEX = 1; -constexpr int STRATEGY_INDEX = 2; -constexpr int ASSETS_INDEX = 3; -constexpr int HASH_KEY_INDEX = 4; -constexpr int PRIMARY_KEY_INDEX = 5; + static int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, + std::vector &cloudPkVals); -int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, - std::vector &cloudPkVals); + static ChangeType OpTypeToChangeType(OpType strategy); -ChangeType OpTypeToChangeType(OpType strategy); + static bool IsSinglePrimaryKey(const std::vector &pKColNames); -bool IsSinglePrimaryKey(const std::vector &pKColNames); + static void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames); -void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames); + static AssetOpType StatusToFlag(AssetStatus status); -AssetOpType StatusToFlag(AssetStatus status); + static void StatusToFlagForAsset(Asset &asset); -void StatusToFlagForAsset(Asset &asset); + static void StatusToFlagForAssets(Assets &assets); -void StatusToFlagForAssets(Assets &assets); + static void StatusToFlagForAssetsInRecord(const std::vector &fields, VBucket &record); -void StatusToFlagForAssetsInRecord(const std::vector &fields, VBucket &record); + static bool IsChangeDataEmpty(const ChangedData &changedData); -bool IsChngDataEmpty(const ChangedData &changedData); + static bool EqualInMsLevel(const Timestamp cmp, const Timestamp beCmp); -bool EqualInMsLevel(const Timestamp cmp, const Timestamp beCmp); + static bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo); -bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo); + static int CheckParamValid(const std::vector &devices, SyncMode mode); + + static LogInfo GetCloudLogInfo(VBucket &datum); + + static int SaveChangedDataByType(const VBucket &datum, ChangedData &changedData, const DataInfoWithLog &localInfo, + ChangeType type); + + static int FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, + size_t &delIdx); + + static int CheckCloudSyncDataValid(const CloudSyncData &uploadData, const std::string &tableName, + const int64_t &count, uint64_t &taskId); + + static void ClearCloudSyncData(CloudSyncData &uploadData); + + static int GetWaterMarkAndUpdateTime(std::vector& extend, Timestamp &waterMark); + + static bool CheckCloudSyncDataEmpty(const CloudSyncData &uploadData); + + static void ModifyCloudDataTime(VBucket &data); + + static int UpdateExtendTime(CloudSyncData &uploadData, const int64_t &count, uint64_t taskId, + Timestamp &waterMark); + + static void UpdateLocalCache(OpType opType, const LogInfo &cloudInfo, + const LogInfo &localInfo, std::map &localLogInfoCache); + + static int SaveChangedData(ICloudSyncer::SyncParam ¶m, size_t dataIndex, const ICloudSyncer::DataInfo &dataInfo, + std::vector> &deletedList); + + static void ClearWithoutData(ICloudSyncer::SyncParam ¶m); +}; } #endif // CLOUD_SYNC_UTILS_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp index 6372294c4904207b5b6b0dfaec8d91f47d7d01ef..05894572048a61f2d25242dfba2244581864611e 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp @@ -20,28 +20,20 @@ #include "cloud/cloud_db_constant.h" #include "cloud/cloud_storage_utils.h" +#include "cloud/icloud_db.h" #include "cloud_sync_tag_assets.h" #include "cloud_sync_utils.h" #include "db_errno.h" -#include "cloud/icloud_db.h" -#include "kv_store_errno.h" #include "log_print.h" -#include "platform_specific.h" #include "runtime_context.h" -#include "strategy_factory.h" #include "storage_proxy.h" #include "store_types.h" +#include "strategy_factory.h" +#include "version.h" namespace DistributedDB { -namespace { - const TaskId INVALID_TASK_ID = 0u; - const int MAX_HEARTBEAT_FAILED_LIMIT = 2; - const int HEARTBEAT_PERIOD = 3; - const int MAX_DOWNLOAD_COMMIT_LIMIT = 5; -} - CloudSyncer::CloudSyncer(std::shared_ptr storageProxy) - : currentTaskId_(INVALID_TASK_ID), + : lastTaskId_(INVALID_TASK_ID), storageProxy_(std::move(storageProxy)), queuedManualSyncLimit_(DBConstant::QUEUED_SYNC_LIMIT_DEFAULT), closed_(false), @@ -58,7 +50,23 @@ CloudSyncer::CloudSyncer(std::shared_ptr storageProxy) int CloudSyncer::Sync(const std::vector &devices, SyncMode mode, const std::vector &tables, const SyncProcessCallback &callback, int64_t waitTime) { - int errCode = CheckParamValid(devices, mode); + CloudTaskInfo taskInfo; + taskInfo.mode = mode; + taskInfo.table = tables; + taskInfo.callback = callback; + taskInfo.timeout = waitTime; + taskInfo.devices = devices; + for (const auto &item: tables) { + QuerySyncObject syncObject; + syncObject.SetTableName(item); + taskInfo.queryList.push_back(syncObject); + } + return Sync(taskInfo); +} + +int CloudSyncer::Sync(const CloudTaskInfo &taskInfo) +{ + int errCode = CloudSyncUtils::CheckParamValid(taskInfo.devices, taskInfo.mode); if (errCode != E_OK) { return errCode; } @@ -68,16 +76,15 @@ int CloudSyncer::Sync(const std::vector &devices, SyncMode mode, if (closed_) { return -E_DB_CLOSED; } - CloudTaskInfo taskInfo; - taskInfo.mode = mode; - taskInfo.table = tables; - taskInfo.callback = callback; - taskInfo.timeout = waitTime; - taskInfo.devices = devices; - errCode = TryToAddSyncTask(std::move(taskInfo)); + CloudTaskInfo info = taskInfo; + info.status = ProcessStatus::PREPARED; + errCode = TryToAddSyncTask(std::move(info)); if (errCode != E_OK) { return errCode; } + if (taskInfo.priorityTask) { + MarkCurrentTaskPausedIfNeed(); + } return TriggerSync(); } @@ -98,15 +105,19 @@ void CloudSyncer::Close() closed_ = true; CloudSyncer::TaskId currentTask; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); currentTask = currentContext_.currentTaskId; } // mark current task db_closed SetTaskFailed(currentTask, -E_DB_CLOSED); + { + std::lock_guard autoLock(dataLock_); + currentContext_.locker = nullptr; + } cloudDB_.Close(); { LOGD("[CloudSyncer] begin wait current task finished"); - std::unique_lock uniqueLock(contextLock_); + std::unique_lock uniqueLock(dataLock_); contextCv_.wait(uniqueLock, [this]() { return currentContext_.currentTaskId == INVALID_TASK_ID; }); @@ -116,11 +127,12 @@ void CloudSyncer::Close() // copy all task from queue std::vector infoList; { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); for (const auto &item: cloudTaskInfos_) { infoList.push_back(item.second); } taskQueue_.clear(); + priorityTaskQueue_.clear(); cloudTaskInfos_.clear(); } // notify all DB_CLOSED @@ -158,25 +170,24 @@ void CloudSyncer::DoSyncIfNeed() if (closed_) { return; } - // get taskId from queue - TaskId triggerTaskId; - { - std::lock_guard autoLock(queueLock_); - if (taskQueue_.empty()) { - return; + // do all sync task in this loop + do { + // get taskId from queue + TaskId triggerTaskId = GetNextTaskId(); + if (triggerTaskId == INVALID_TASK_ID) { + LOGD("[CloudSyncer] task queue empty"); + break; } - triggerTaskId = taskQueue_.front(); - } - // pop taskId in queue - if (PrepareSync(triggerTaskId) != E_OK) { - return; - } - // do sync logic - int errCode = DoSync(triggerTaskId); - // finished after sync - DoFinished(triggerTaskId, errCode, {}); - // do next task async - (void)TriggerSync(); + // pop taskId in queue + if (PrepareSync(triggerTaskId) != E_OK) { + break; + } + // do sync logic + int errCode = DoSync(triggerTaskId); + // finished after sync + DoFinished(triggerTaskId, errCode); + } while (!closed_); + LOGD("[CloudSyncer] DoSyncIfNeed finished, closed status %d", static_cast(closed_)); } int CloudSyncer::DoSync(TaskId taskId) @@ -184,23 +195,20 @@ int CloudSyncer::DoSync(TaskId taskId) std::lock_guard lock(syncMutex_); CloudTaskInfo taskInfo; { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); taskInfo = cloudTaskInfos_[taskId]; } - int errCode = LockCloud(taskId); + int errCode = LockCloudIfNeed(taskId); if (errCode != E_OK) { return errCode; } bool needUpload = true; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); needUpload = currentContext_.strategy->JudgeUpload(); } errCode = DoSyncInner(taskInfo, needUpload); - int unlockCode = UnlockCloud(); - if (errCode == E_OK) { - errCode = unlockCode; - } + UnlockIfNeed(); return errCode; } @@ -211,20 +219,20 @@ int CloudSyncer::DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUp } int errCode = storageProxy_->StartTransaction(); if (errCode != E_OK) { - LOGE("[CloudSyncer] start transaction Failed before doing upload."); + LOGE("[CloudSyncer] start transaction failed before doing upload."); return errCode; } - for (size_t i = 0; i < taskInfo.table.size(); ++i) { + for (size_t i = GetStartTableIndex(taskInfo.taskId, true); i < taskInfo.table.size(); ++i) { LOGD("[CloudSyncer] try upload table, index: %zu", i); + { + std::lock_guard autoLock(dataLock_); + currentContext_.tableName = taskInfo.table[i]; + } errCode = CheckTaskIdValid(taskInfo.taskId); if (errCode != E_OK) { LOGE("[CloudSyncer] task is invalid, abort sync"); break; } - { - std::lock_guard autoLock(contextLock_); - currentContext_.tableName = taskInfo.table[i]; - } errCode = DoUpload(taskInfo.taskId, i == (taskInfo.table.size() - 1u)); if (errCode != E_OK) { LOGE("[CloudSyncer] upload failed %d", errCode); @@ -236,7 +244,11 @@ int CloudSyncer::DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUp break; } } - if (errCode == E_OK) { + if (errCode == -E_TASK_PAUSED) { + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[taskInfo.taskId].upload = true; + } + if (errCode == E_OK || errCode == -E_TASK_PAUSED) { int commitErrorCode = storageProxy_->Commit(); if (commitErrorCode != E_OK) { LOGE("[CloudSyncer] cannot commit transaction: %d.", commitErrorCode); @@ -253,17 +265,17 @@ int CloudSyncer::DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUp int CloudSyncer::DoSyncInner(const CloudTaskInfo &taskInfo, const bool needUpload) { int errCode = E_OK; - for (size_t i = 0; i < taskInfo.table.size(); ++i) { + for (size_t i = GetStartTableIndex(taskInfo.taskId, false); i < taskInfo.table.size(); ++i) { LOGD("[CloudSyncer] try download table, index: %zu", i); + { + std::lock_guard autoLock(dataLock_); + currentContext_.tableName = taskInfo.table[i]; + } errCode = CheckTaskIdValid(taskInfo.taskId); if (errCode != E_OK) { - LOGE("[CloudSyncer] task is invalid, abort sync"); + LOGW("[CloudSyncer] task is invalid, abort sync"); return errCode; } - { - std::lock_guard autoLock(contextLock_); - currentContext_.tableName = taskInfo.table[i]; - } errCode = DoDownload(taskInfo.taskId); if (errCode != E_OK) { LOGE("[CloudSyncer] download failed %d", errCode); @@ -282,144 +294,21 @@ int CloudSyncer::DoSyncInner(const CloudTaskInfo &taskInfo, const bool needUploa return DoUploadInNeed(taskInfo, needUpload); } -void CloudSyncer::DoFinished(TaskId taskId, int errCode, const InnerProcessInfo &processInfo) +void CloudSyncer::DoFinished(TaskId taskId, int errCode) { - { - std::lock_guard autoLock(queueLock_); - taskQueue_.remove(taskId); - } - std::shared_ptr notifier = nullptr; - { - // check current task is running or not - std::lock_guard autoLock(contextLock_); - if (currentContext_.currentTaskId != taskId) { // should not happen - LOGW("[CloudSyncer] taskId %" PRIu64 " not exist in context!", taskId); - return; - } - currentContext_.currentTaskId = INVALID_TASK_ID; - notifier = currentContext_.notifier; - currentContext_.notifier = nullptr; - currentContext_.strategy = nullptr; - currentContext_.tableName.clear(); - currentContext_.assetDownloadList.clear(); - currentContext_.assetFields.clear(); - currentContext_.assetsInfo.clear(); - currentContext_.cloudWaterMarks.clear(); + if (errCode == -E_TASK_PAUSED) { + LOGD("[CloudSyncer] taskId %" PRIu64 " was paused, it won't be finished now", taskId); + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[taskId].context = std::move(currentContext_); + ClearCurrentContextWithoutLock(); + return; } - CloudTaskInfo info; { - std::lock_guard autoLock(queueLock_); - if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { // should not happen - LOGW("[CloudSyncer] taskId %" PRIu64 " has been finished!", taskId); - contextCv_.notify_one(); - return; - } - info = std::move(cloudTaskInfos_[taskId]); - cloudTaskInfos_.erase(taskId); - } - contextCv_.notify_one(); - if (info.errCode == E_OK) { - info.errCode = errCode; - } - LOGI("[CloudSyncer] finished taskId %" PRIu64 " errCode %d", taskId, info.errCode); - info.status = ProcessStatus::FINISHED; - if (notifier != nullptr) { - notifier->NotifyProcess(info, processInfo, true); - } -} - -static int SaveChangedDataByType(const VBucket &datum, ChangedData &changedData, const DataInfoWithLog &localInfo, - ChangeType type) -{ - int ret = E_OK; - std::vector cloudPkVals; - if (type == ChangeType::OP_DELETE) { - ret = GetCloudPkVals(localInfo.primaryKeys, changedData.field, localInfo.logInfo.dataKey, cloudPkVals); - } else { - ret = GetCloudPkVals(datum, changedData.field, localInfo.logInfo.dataKey, cloudPkVals); - } - if (ret != E_OK) { - return ret; - } - changedData.primaryData[type].emplace_back(std::move(cloudPkVals)); - return E_OK; -} - -int CloudSyncer::FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, - size_t &delIdx) -{ - for (std::pair pair : deletedList) { - if (pair.first == hashKey) { - delIdx = pair.second; - return E_OK; - } - } - return -E_INTERNAL_ERROR; -} - -int CloudSyncer::SaveChangedData(SyncParam ¶m, int dataIndex, const DataInfo &dataInfo, - std::vector> &deletedList) -{ - OpType opType = param.downloadData.opType[dataIndex]; - Key hashKey = dataInfo.localInfo.logInfo.hashKey; - if (param.deletePrimaryKeySet.find(hashKey) != param.deletePrimaryKeySet.end()) { - if (opType == OpType::INSERT) { - size_t delIdx; - int errCode = FindDeletedListIndex(deletedList, hashKey, delIdx); - if (errCode != E_OK) { - LOGE("[CloudSyncer] FindDeletedListIndex could not find delete item."); - return errCode; - } - param.changedData.primaryData[ChangeType::OP_DELETE].erase( - param.changedData.primaryData[ChangeType::OP_DELETE].begin() + delIdx); - (void)param.dupHashKeySet.insert(hashKey); - opType = OpType::UPDATE; - // only composite primary key needs to be processed. - if (!param.isSinglePrimaryKey) { - param.withoutRowIdData.updateData.push_back(std::make_tuple(dataIndex, - param.changedData.primaryData[ChangeType::OP_UPDATE].size())); - } - } else if (opType == OpType::DELETE) { - std::pair pair{hashKey, static_cast( - param.changedData.primaryData[ChangeType::OP_DELETE].size())}; - deletedList.emplace_back(pair); - } else { - LOGW("[CloudSyncer] deletePrimaryKeySet ignore opType %d.", opType); - } - } - // INSERT: for no primary key or composite primary key situation - if (!param.isSinglePrimaryKey && opType == OpType::INSERT) { - param.withoutRowIdData.insertData.push_back(dataIndex); - return E_OK; - } - switch (opType) { - // INSERT: only for single primary key situation - case OpType::INSERT: - return SaveChangedDataByType( - param.downloadData.data[dataIndex], param.changedData, dataInfo.localInfo, ChangeType::OP_INSERT); - case OpType::UPDATE: - if (NeedSaveData(dataInfo.localInfo.logInfo, dataInfo.cloudLogInfo)) { - return SaveChangedDataByType(param.downloadData.data[dataIndex], param.changedData, - dataInfo.localInfo, ChangeType::OP_UPDATE); - } - break; - case OpType::DELETE: - return SaveChangedDataByType(param.downloadData.data[dataIndex], param.changedData, - dataInfo.localInfo, ChangeType::OP_DELETE); - default: - break; + std::lock_guard autoLock(dataLock_); + taskQueue_.remove(taskId); + priorityTaskQueue_.remove(taskId); } - return E_OK; -} - -static LogInfo GetCloudLogInfo(VBucket &datum) -{ - LogInfo cloudLogInfo = { 0 }; - cloudLogInfo.timestamp = (Timestamp)std::get(datum[CloudDbConstant::MODIFY_FIELD]); - cloudLogInfo.wTimestamp = (Timestamp)std::get(datum[CloudDbConstant::CREATE_FIELD]); - cloudLogInfo.flag = (std::get(datum[CloudDbConstant::DELETE_FIELD])) ? 1u : 0u; - cloudLogInfo.cloudGid = std::get(datum[CloudDbConstant::GID_FIELD]); - return cloudLogInfo; + ClearContextAndNotify(taskId, errCode); } /** @@ -434,7 +323,7 @@ int CloudSyncer::UpdateChangedData(SyncParam ¶m, DownloadList &assetsDownloa for (size_t j : param.withoutRowIdData.insertData) { VBucket &datum = param.downloadData.data[j]; std::vector primaryValues; - ret = GetCloudPkVals(datum, param.changedData.field, + ret = CloudSyncUtils::GetCloudPkVals(datum, param.changedData.field, std::get(datum[CloudDbConstant::ROW_ID_FIELD_NAME]), primaryValues); if (ret != E_OK) { LOGE("[CloudSyncer] updateChangedData cannot get primaryValues"); @@ -483,10 +372,10 @@ bool CloudSyncer::IsDataContainDuplicateAsset(const std::vector &assetFie bool CloudSyncer::IsDataContainAssets() { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); bool hasTable = (currentContext_.assetFields.find(currentContext_.tableName) != currentContext_.assetFields.end()); if (!hasTable) { - LOGW("[CloudSyncer] failed to get assetFields, because tableName doesn't exit in currentContext, %d.", + LOGW("[CloudSyncer] failed to get assetFields, because tableName doesn't exist in currentContext, %d.", -E_INTERNAL_ERROR); return false; } @@ -529,7 +418,7 @@ std::map CloudSyncer::TagAssetsInSingleRecord(VBucket &cove std::map res = {}; std::vector assetFields; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); assetFields = currentContext_.assetFields[currentContext_.tableName]; } // For every column contain asset or assets, assetFields are in context @@ -577,6 +466,7 @@ int CloudSyncer::HandleDownloadResult(const std::string &tableName, DownloadComm } errCode = storageProxy_->SetLogTriggerStatus(false); if (errCode != E_OK) { + (void)storageProxy_->Rollback(); return errCode; } for (size_t i = 0; i < commitList.size(); i++) { @@ -616,41 +506,36 @@ int CloudSyncer::HandleDownloadResult(const std::string &tableName, DownloadComm return errCode; } -int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, const DownloadList &downloadList, +int CloudSyncer::CloudDbDownloadAssets(TaskId taskId, InnerProcessInfo &info, const DownloadList &downloadList, const std::set &dupHashKeySet, ChangedData &changedAssets) { int downloadStatus = E_OK; + { + std::lock_guard autoLock(dataLock_); + downloadStatus = resumeTaskInfos_[taskId].downloadStatus; + resumeTaskInfos_[taskId].downloadStatus = E_OK; + } + int errorCode = E_OK; DownloadCommitList commitList; - for (size_t i = 0; i < downloadList.size(); i++) { + for (size_t i = GetDownloadAssetIndex(taskId); i < downloadList.size(); i++) { + errorCode = CheckTaskIdValid(taskId); + if (errorCode != E_OK) { + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[taskId].lastDownloadIndex = i; + resumeTaskInfos_[taskId].downloadStatus = downloadStatus; + break; + } DownloadItem downloadItem; GetDownloadItem(downloadList, i, downloadItem); - std::map downloadAssets(downloadItem.assets); - CloudStorageUtils::EraseNoChangeAsset(downloadAssets); - if (downloadAssets.empty()) { // Download data (include deleting) - continue; - } - int errorCode = cloudDB_.Download(info.tableName, downloadItem.gid, downloadItem.prefix, downloadAssets); + errorCode = DownloadOneAssetRecord(dupHashKeySet, downloadList, downloadItem, info, changedAssets); if (errorCode == -E_NOT_SET) { info.downLoadInfo.failCount += (downloadList.size() - i); info.downLoadInfo.successCount -= (downloadList.size() - i); - return -E_NOT_SET; - } - if (errorCode != E_OK) { - info.downLoadInfo.failCount += 1; - info.downLoadInfo.successCount -= 1; + return errorCode; } - if (dupHashKeySet.find(downloadItem.hashKey) == dupHashKeySet.end()) { - changedAssets.primaryData[OpTypeToChangeType(downloadItem.strategy)].push_back( - downloadItem.primaryKeyValList); - } else if (downloadItem.strategy == OpType::INSERT) { - changedAssets.primaryData[ChangeType::OP_UPDATE].push_back(downloadItem.primaryKeyValList); - } - - // If the assets are DELETE, needn't fill back cloud assets. if (downloadItem.strategy == OpType::DELETE) { continue; } - CloudStorageUtils::MergeDownloadAsset(downloadAssets, downloadItem.assets); // Process result of each asset commitList.push_back(std::make_tuple(downloadItem.gid, std::move(downloadItem.assets), errorCode == E_OK)); downloadStatus = downloadStatus == E_OK ? errorCode : downloadStatus; @@ -661,22 +546,22 @@ int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, const DownloadLis } } } + LOGD("Download status is %d", downloadStatus); int ret = CommitDownloadResult(info, commitList); if (ret != E_OK) { return ret; } - LOGD("Download status is %d", downloadStatus); - return downloadStatus; + return errorCode == E_OK ? downloadStatus : errorCode; } void CloudSyncer::GetDownloadItem(const DownloadList &downloadList, size_t i, DownloadItem &downloadItem) { - downloadItem.gid = std::get(downloadList[i]); - downloadItem.prefix = std::get(downloadList[i]); - downloadItem.strategy = std::get(downloadList[i]); - downloadItem.assets = std::get(downloadList[i]); - downloadItem.hashKey = std::get(downloadList[i]); - downloadItem.primaryKeyValList = std::get(downloadList[i]); + downloadItem.gid = std::get(downloadList[i]); + downloadItem.prefix = std::get(downloadList[i]); + downloadItem.strategy = std::get(downloadList[i]); + downloadItem.assets = std::get(downloadList[i]); + downloadItem.hashKey = std::get(downloadList[i]); + downloadItem.primaryKeyValList = std::get(downloadList[i]); } int CloudSyncer::DownloadAssets(InnerProcessInfo &info, const std::vector &pKColNames, @@ -686,7 +571,7 @@ int CloudSyncer::DownloadAssets(InnerProcessInfo &info, const std::vector autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); changeList = currentContext_.assetDownloadList; + taskId = currentContext_.currentTaskId; } // Download data (include deleting) will handle return Code in this situation - int ret = CloudDbDownloadAssets(info, changeList, dupHashKeySet, changedAssets); + int ret = CloudDbDownloadAssets(taskId, info, changeList, dupHashKeySet, changedAssets); if (ret != E_OK) { LOGE("[CloudSyncer] Can not download assets or can not handle download result %d", ret); - return ret; } return ret; } @@ -714,7 +600,7 @@ std::map CloudSyncer::GetAssetsFromVBucket(VBucket &data) std::map assets; std::vector fields; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); fields = currentContext_.assetFields[currentContext_.tableName]; } for (const auto &field : fields) { @@ -759,7 +645,7 @@ int CloudSyncer::TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam &pa case OpType::INSERT: case OpType::UPDATE: case OpType::DELETE: - ret = HandleTagAssets(hashKey, idx, param, dataInfo, localAssetInfo); + ret = HandleTagAssets(hashKey, dataInfo, idx, param, localAssetInfo); break; case OpType::NOT_HANDLE: case OpType::ONLY_UPDATE_GID: @@ -767,7 +653,7 @@ int CloudSyncer::TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam &pa // Save the asset info into context std::map assetsMap = GetAssetsFromVBucket(param.downloadData.data[idx]); { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (currentContext_.assetsInfo.find(param.tableName) == currentContext_.assetsInfo.end()) { currentContext_.assetsInfo[param.tableName] = {}; } @@ -781,15 +667,15 @@ int CloudSyncer::TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam &pa return ret; } -int CloudSyncer::HandleTagAssets(const Key &hashKey, size_t idx, SyncParam ¶m, DataInfo &dataInfo, +int CloudSyncer::HandleTagAssets(const Key &hashKey, const DataInfo &dataInfo, size_t idx, SyncParam ¶m, VBucket &localAssetInfo) { Type prefix; std::vector pkVals; OpType strategy = param.downloadData.opType[idx]; bool isDelStrategy = (strategy == OpType::DELETE); - int ret = GetCloudPkVals(isDelStrategy ? dataInfo.localInfo.primaryKeys : param.downloadData.data[idx], - param.pkColNames, dataInfo.localInfo.logInfo.dataKey, pkVals); + int ret = CloudSyncUtils::GetCloudPkVals(isDelStrategy ? dataInfo.localInfo.primaryKeys : + param.downloadData.data[idx], param.pkColNames, dataInfo.localInfo.logInfo.dataKey, pkVals); if (ret != E_OK) { LOGE("[CloudSyncer] HandleTagAssets cannot get primary key value list. %d", ret); return ret; @@ -802,7 +688,7 @@ int CloudSyncer::HandleTagAssets(const Key &hashKey, size_t idx, SyncParam ¶ std::map assetsMap = TagAssetsInSingleRecord(param.downloadData.data[idx], localAssetInfo, false, ret); if (ret != E_OK) { - LOGE("[CloudSyncer] TagAssetsInSingleRecord report ERROR"); + LOGE("[CloudSyncer] TagAssetsInSingleRecord report ERROR in download data"); return ret; } @@ -843,7 +729,7 @@ int CloudSyncer::SaveDatum(SyncParam ¶m, size_t idx, std::vector> deletedList; // use for record local delete status std::map localLogInfoCache; @@ -907,7 +786,7 @@ int CloudSyncer::SaveData(SyncParam ¶m) } // Save assetsMap into current context { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); currentContext_.assetDownloadList = param.assetsDownloadList; } // save the data to the database by batch, downloadData will return rowid when insert data. @@ -939,7 +818,7 @@ int CloudSyncer::PreCheck(CloudSyncer::TaskId &taskId, const TableName &tableNam return ret; } { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { LOGE("[CloudSyncer] Cloud Task Info does not exist taskId: , %" PRIu64 ".", taskId); return -E_INVALID_ARGS; @@ -959,13 +838,15 @@ int CloudSyncer::PreCheck(CloudSyncer::TaskId &taskId, const TableName &tableNam bool CloudSyncer::NeedNotifyChangedData(const ChangedData &changedData) { + TaskId taskId; { - std::lock_guard autoLock(contextLock_); - if (IsModeForcePush(currentContext_.currentTaskId)) { - return false; - } + std::lock_guard autoLock(dataLock_); + taskId = currentContext_.currentTaskId; + } + if (IsModeForcePush(taskId)) { + return false; } - // when there have no data been changed, it needn't notified + // when there have no data been changed, it don't need fill back if (changedData.primaryData[OP_INSERT].empty() && changedData.primaryData[OP_UPDATE].empty() && changedData.primaryData[OP_DELETE].empty()) { return false; @@ -980,7 +861,7 @@ int CloudSyncer::NotifyChangedData(ChangedData &&changedData) } std::string deviceName; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); std::vector devices = currentContext_.notifier->GetDevices(); if (devices.empty()) { LOGE("[CloudSyncer] CurrentContext do not contain device info"); @@ -998,23 +879,17 @@ int CloudSyncer::NotifyChangedData(ChangedData &&changedData) void CloudSyncer::NotifyInDownload(CloudSyncer::TaskId taskId, SyncParam ¶m) { - CloudTaskInfo taskInfo; - { - std::lock_guard autoLock(queueLock_); - taskInfo = cloudTaskInfos_[taskId]; - } - std::lock_guard autoLock(contextLock_); - + std::lock_guard autoLock(dataLock_); if (currentContext_.strategy->JudgeUpload()) { - currentContext_.notifier->NotifyProcess(taskInfo, param.info); + currentContext_.notifier->NotifyProcess(cloudTaskInfos_[taskId], param.info); } else { if (param.isLastBatch) { param.info.tableStatus = ProcessStatus::FINISHED; } - if (taskInfo.table.back() == param.tableName && param.isLastBatch) { + if (cloudTaskInfos_[taskId].table.back() == param.tableName && param.isLastBatch) { currentContext_.notifier->UpdateProcess(param.info); } else { - currentContext_.notifier->NotifyProcess(taskInfo, param.info); + currentContext_.notifier->NotifyProcess(cloudTaskInfos_[taskId], param.info); } } } @@ -1052,27 +927,47 @@ int CloudSyncer::SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam &pa int CloudSyncer::SaveDataNotifyProcess(CloudSyncer::TaskId taskId, SyncParam ¶m) { ChangedData changedData; - param.changedData = changedData; - param.downloadData.opType.resize(param.downloadData.data.size()); - int ret = SaveDataInTransaction(taskId, param); - if (ret != E_OK) { - return ret; + bool skipSave = false; + { + bool currentTableResume = IsCurrentTableResume(taskId, false); + std::lock_guard autoLock(dataLock_); + if (currentTableResume && resumeTaskInfos_[currentContext_.currentTaskId].skipQuery) { + skipSave = true; + } } - // call OnChange to notify changedData object first time (without Assets) - ret = NotifyChangedData(std::move(param.changedData)); - if (ret != E_OK) { - LOGE("[CloudSyncer] Cannot notify changed data due to error %d", ret); - return ret; + int ret; + if (!skipSave) { + param.changedData = changedData; + param.downloadData.opType.resize(param.downloadData.data.size()); + ret = SaveDataInTransaction(taskId, param); + if (ret != E_OK) { + return ret; + } + // call OnChange to notify changedData object first time (without Assets) + ret = NotifyChangedData(std::move(param.changedData)); + if (ret != E_OK) { + LOGE("[CloudSyncer] Cannot notify changed data due to error %d", ret); + return ret; + } } // Begin downloading assets ChangedData changedAssets; ret = DownloadAssets(param.info, param.pkColNames, param.dupHashKeySet, changedAssets); (void)NotifyChangedData(std::move(changedAssets)); + if (ret == -E_TASK_PAUSED) { + LOGD("[CloudSyncer] current task was paused, abort download asset"); + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[currentContext_.currentTaskId].skipQuery = true; + return ret; + } else if (skipSave) { + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[currentContext_.currentTaskId].skipQuery = false; + } if (ret != E_OK) { LOGE("[CloudSyncer] Cannot notify downloadAssets due to error %d", ret); return ret; } - UpdateCloudWaterMark(param); + UpdateCloudWaterMark(taskId, param); return E_OK; } @@ -1081,10 +976,10 @@ void CloudSyncer::NotifyInBatchUpload(const UploadParam &uploadParam, const Inne { CloudTaskInfo taskInfo; { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); taskInfo = cloudTaskInfos_[uploadParam.taskId]; } - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (uploadParam.lastTable && lastBatch) { currentContext_.notifier->UpdateProcess(innerProcessInfo); } else { @@ -1095,33 +990,17 @@ void CloudSyncer::NotifyInBatchUpload(const UploadParam &uploadParam, const Inne int CloudSyncer::DoDownload(CloudSyncer::TaskId taskId) { SyncParam param; - int ret = GetCurrentTableName(param.tableName); - if (ret != E_OK) { - LOGE("[CloudSyncer] Invalid table name for syncing: %d", ret); - return ret; - } - param.info.tableName = param.tableName; - std::vector assetFields; - // only no primary key and composite primary key contains rowid. - ret = storageProxy_->GetPrimaryColNamesWithAssetsFields(param.tableName, param.pkColNames, assetFields); - if (ret != E_OK) { - LOGE("[CloudSyncer] Cannot get primary column names: %d", ret); - return ret; + int errCode = GetSyncParamForDownload(taskId, param); + if (errCode != E_OK) { + LOGE("[CloudSyncer] get sync param for download failed %d", errCode); + return errCode; } - { - std::lock_guard autoLock(contextLock_); - currentContext_.assetFields[currentContext_.tableName] = assetFields; + errCode = DoDownloadInner(taskId, param); + if (errCode == -E_TASK_PAUSED) { + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[taskId].syncParam = std::move(param); } - param.isSinglePrimaryKey = IsSinglePrimaryKey(param.pkColNames); - param.cloudWaterMark = ""; - if (!IsModeForcePull(taskId)) { - ret = storageProxy_->GetCloudWaterMark(param.tableName, param.cloudWaterMark); - if (ret != E_OK) { - LOGE("[CloudSyncer] Cannot get cloud water level from cloud meta data: %d.", ret); - return ret; - } - } - return DoDownloadInner(taskId, param); + return errCode; } int CloudSyncer::DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m) @@ -1131,49 +1010,19 @@ int CloudSyncer::DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m) if (ret != E_OK) { return ret; } - bool queryEnd = false; - while (!queryEnd) { - // Get cloud data after cloud water mark - param.info.tableStatus = ProcessStatus::PROCESSING; - DownloadData downloadData; - param.downloadData = downloadData; - param.isLastBatch = false; - ret = QueryCloudData(param.info.tableName, param.cloudWaterMark, param.downloadData); - if (ret == -E_QUERY_END) { - // Won't break here since downloadData may not be null - queryEnd = true; - param.isLastBatch = true; - } else if (ret != E_OK) { - std::lock_guard autoLock(contextLock_); - param.info.tableStatus = ProcessStatus::FINISHED; - currentContext_.notifier->UpdateProcess(param.info); - return ret; - } - if (param.downloadData.data.empty()) { - if (ret == E_OK) { - LOGD("[CloudSyncer] try to query cloud data use increment water mark"); - UpdateCloudWaterMark(param); - continue; - } - NotifyInEmptyDownload(taskId, param.info); - break; - } - // Save data in transaction, update cloud water mark, notify process and changed data - ret = SaveDataNotifyProcess(taskId, param); + param.isLastBatch = false; + while (!param.isLastBatch) { + ret = DownloadOneBatch(taskId, param); if (ret != E_OK) { - std::lock_guard autoLock(contextLock_); - param.info.tableStatus = ProcessStatus::FINISHED; - currentContext_.notifier->UpdateProcess(param.info); return ret; } - (void)NotifyInDownload(taskId, param); } return E_OK; } void CloudSyncer::NotifyInEmptyDownload(CloudSyncer::TaskId taskId, InnerProcessInfo &info) { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (currentContext_.strategy->JudgeUpload()) { currentContext_.notifier->NotifyProcess(cloudTaskInfos_[taskId], info); } else { @@ -1193,7 +1042,7 @@ int CloudSyncer::PreCheckUpload(CloudSyncer::TaskId &taskId, const TableName &ta return ret; } { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { LOGE("[CloudSyncer] Cloud Task Info does not exist taskId: %" PRIu64 ".", taskId); return -E_INVALID_ARGS; @@ -1206,7 +1055,7 @@ int CloudSyncer::PreCheckUpload(CloudSyncer::TaskId &taskId, const TableName &ta } } - if (!IsModeForcePush(taskId)) { + if (!IsModeForcePush(taskId) && !IsPriorityTask(taskId)) { ret = storageProxy_->GetLocalWaterMark(tableName, localMark); if (ret != E_OK) { LOGE("[CloudSyncer] Failed to get local water mark when upload, %d.", ret); @@ -1215,13 +1064,6 @@ int CloudSyncer::PreCheckUpload(CloudSyncer::TaskId &taskId, const TableName &ta return ret; } -bool CloudSyncer::CheckCloudSyncDataEmpty(const CloudSyncData &uploadData) -{ - return uploadData.insData.extend.empty() && uploadData.insData.record.empty() && - uploadData.updData.extend.empty() && uploadData.updData.record.empty() && - uploadData.delData.extend.empty() && uploadData.delData.record.empty(); -} - int CloudSyncer::DoBatchUpload(CloudSyncData &uploadData, UploadParam &uploadParam, InnerProcessInfo &innerProcessInfo) { int errCode = E_OK; @@ -1286,7 +1128,7 @@ int CloudSyncer::PutWaterMarkAfterBatchUpload(const std::string &tableName, Uplo { int errCode = E_OK; // if we use local cover cloud strategy, it won't update local water mark also. - if (IsModeForcePush(uploadParam.taskId)) { + if (IsModeForcePush(uploadParam.taskId) || IsPriorityTask(uploadParam.taskId)) { return E_OK; } errCode = storageProxy_->PutLocalWaterMark(tableName, uploadParam.localMark); @@ -1311,9 +1153,10 @@ int CloudSyncer::DoUpload(CloudSyncer::TaskId taskId, bool lastTable) LOGE("[CloudSyncer] Doing upload sync pre check failed, %d.", ret); return ret; } + ReloadWaterMarkIfNeed(taskId, localMark); int64_t count = 0; - ret = storageProxy_->GetUploadCount(tableName, localMark, IsModeForcePush(taskId), count); + ret = storageProxy_->GetUploadCount(GetQuerySyncObject(tableName), localMark, IsModeForcePush(taskId), count); if (ret != E_OK) { // GetUploadCount will return E_OK when upload count is zero. LOGE("[CloudSyncer] Failed to get Upload Data Count, %d.", ret); @@ -1326,7 +1169,7 @@ int CloudSyncer::DoUpload(CloudSyncer::TaskId taskId, bool lastTable) innerProcessInfo.upLoadInfo.total = 0; // count is zero innerProcessInfo.tableStatus = ProcessStatus::FINISHED; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (lastTable) { currentContext_.notifier->UpdateProcess(innerProcessInfo); } else { @@ -1351,7 +1194,7 @@ int CloudSyncer::TagUploadAssets(CloudSyncData &uploadData) } std::map> cloudAssets; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); cloudAssets = currentContext_.assetsInfo[currentContext_.tableName]; } // for delete scenario, assets should not appear in the records. Thereby we needn't tag the assests. @@ -1381,10 +1224,10 @@ int CloudSyncer::TagUploadAssets(CloudSyncData &uploadData) // In this case, we directly upload data without compartion and tagging std::vector assetFields; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); assetFields = currentContext_.assetFields[currentContext_.tableName]; } - StatusToFlagForAssetsInRecord(assetFields, uploadData.updData.record[i]); + CloudSyncUtils::StatusToFlagForAssetsInRecord(assetFields, uploadData.updData.record[i]); continue; } for (const auto &it : cloudAssets[gid]) { @@ -1407,7 +1250,8 @@ int CloudSyncer::PreProcessBatchUpload(TaskId taskId, const InnerProcessInfo &in if (ret != E_OK) { return ret; } - ret = CheckCloudSyncDataValid(uploadData, innerProcessInfo.tableName, innerProcessInfo.upLoadInfo.total, taskId); + ret = CloudSyncUtils::CheckCloudSyncDataValid(uploadData, innerProcessInfo.tableName, + innerProcessInfo.upLoadInfo.total, taskId); if (ret != E_OK) { LOGE("[CloudSyncer] Invalid Cloud Sync Data of Upload, %d.", ret); return ret; @@ -1418,7 +1262,7 @@ int CloudSyncer::PreProcessBatchUpload(TaskId taskId, const InnerProcessInfo &in return ret; } // get local water mark to be updated in future. - ret = UpdateExtendTime(uploadData, innerProcessInfo.upLoadInfo.total, taskId, localMark); + ret = CloudSyncUtils::UpdateExtendTime(uploadData, innerProcessInfo.upLoadInfo.total, taskId, localMark); if (ret != E_OK) { LOGE("[CloudSyncer] Failed to get new local water mark in Cloud Sync Data, %d.", ret); } @@ -1429,7 +1273,7 @@ int CloudSyncer::SaveCloudWaterMark(const TableName &tableName) { std::string cloudWaterMark; { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (currentContext_.cloudWaterMarks.find(tableName) == currentContext_.cloudWaterMarks.end()) { LOGD("[CloudSyncer] Not found water mark just return"); return E_OK; @@ -1445,43 +1289,45 @@ int CloudSyncer::SaveCloudWaterMark(const TableName &tableName) void CloudSyncer::SetUploadDataFlag(const TaskId taskId, CloudSyncData& uploadData) { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); uploadData.isCloudForcePushStrategy = (cloudTaskInfos_[taskId].mode == SYNC_MODE_CLOUD_FORCE_PUSH); } bool CloudSyncer::IsModeForcePush(const TaskId taskId) { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); return cloudTaskInfos_[taskId].mode == SYNC_MODE_CLOUD_FORCE_PUSH; } bool CloudSyncer::IsModeForcePull(const TaskId taskId) { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); return cloudTaskInfos_[taskId].mode == SYNC_MODE_CLOUD_FORCE_PULL; } +bool CloudSyncer::IsPriorityTask(TaskId taskId) +{ + std::lock_guard autoLock(dataLock_); + return cloudTaskInfos_[taskId].priorityTask; +} + int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &uploadParam) { ContinueToken continueStmtToken = nullptr; CloudSyncData uploadData(tableName); SetUploadDataFlag(uploadParam.taskId, uploadData); - - int ret = storageProxy_->GetCloudData(tableName, uploadParam.localMark, continueStmtToken, uploadData); + int ret = storageProxy_->GetCloudData(GetQuerySyncObject(tableName), uploadParam.localMark, continueStmtToken, + uploadData); if ((ret != E_OK) && (ret != -E_UNFINISHED)) { LOGE("[CloudSyncer] Failed to get cloud data when upload, %d.", ret); return ret; } + uploadParam.count -= uploadData.ignoredCount; - InnerProcessInfo info; - info.tableName = tableName; - info.tableStatus = ProcessStatus::PROCESSING; - info.upLoadInfo.total = static_cast(uploadParam.count); - uint32_t batchIndex = 0; - bool getDataUnfinished = false; + InnerProcessInfo info = GetInnerProcessInfo(tableName, uploadParam); + uint32_t batchIndex = GetCurrentTableUploadBatchIndex(); - while (!CheckCloudSyncDataEmpty(uploadData)) { - getDataUnfinished = (ret == -E_UNFINISHED); + while (!CloudSyncUtils::CheckCloudSyncDataEmpty(uploadData)) { ret = PreProcessBatchUpload(uploadParam.taskId, info, uploadData, uploadParam.localMark); if (ret != E_OK) { break; @@ -1490,13 +1336,7 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload ret = DoBatchUpload(uploadData, uploadParam, info); if (ret != E_OK) { - LOGE("[CloudSyncer] Failed to do upload, %d", ret); - info.upLoadInfo.failCount = info.upLoadInfo.total - info.upLoadInfo.successCount; - info.tableStatus = ProcessStatus::FINISHED; - { - std::lock_guard autoLock(contextLock_); - currentContext_.notifier->UpdateProcess(info); - } + NotifyUploadFailed(ret, info); break; } @@ -1507,14 +1347,19 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload } SetUploadDataFlag(uploadParam.taskId, uploadData); + RecordWaterMark(uploadParam.taskId, uploadParam.localMark); ret = storageProxy_->GetCloudDataNext(continueStmtToken, uploadData); if ((ret != E_OK) && (ret != -E_UNFINISHED)) { LOGE("[CloudSyncer] Failed to get cloud data next when doing upload, %d.", ret); break; } + info.upLoadInfo.total -= static_cast(uploadData.ignoredCount); } - - if (getDataUnfinished) { + if (ret != -E_TASK_PAUSED) { + // reset watermark to zero when task no paused + RecordWaterMark(uploadParam.taskId, 0u); + } + if (continueStmtToken != nullptr) { storageProxy_->ReleaseContinueToken(continueStmtToken); } return ret; @@ -1543,9 +1388,9 @@ int CloudSyncer::PreHandleData(VBucket &datum, const std::vector &p } if (std::get(datum[CloudDbConstant::DELETE_FIELD])) { - RemoveDataExceptExtendInfo(datum, pkColNames); + CloudSyncUtils::RemoveDataExceptExtendInfo(datum, pkColNames); } - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (IsDataContainDuplicateAsset(currentContext_.assetFields[currentContext_.tableName], datum)) { LOGE("[CloudSyncer] Cloud data contain duplicate asset"); return -E_CLOUD_ERROR; @@ -1553,13 +1398,15 @@ int CloudSyncer::PreHandleData(VBucket &datum, const std::vector &p return E_OK; } -int CloudSyncer::QueryCloudData(const std::string &tableName, std::string &cloudWaterMark, +int CloudSyncer::QueryCloudData(TaskId taskId, const std::string &tableName, std::string &cloudWaterMark, DownloadData &downloadData) { - VBucket extend = { - {CloudDbConstant::CURSOR_FIELD, cloudWaterMark} - }; - int ret = cloudDB_.Query(tableName, extend, downloadData.data); + VBucket extend; + int ret = FillDownloadExtend(taskId, tableName, cloudWaterMark, extend); + if (ret != E_OK) { + return ret; + } + ret = cloudDB_.Query(tableName, extend, downloadData.data); if (ret == -E_QUERY_END) { LOGD("[CloudSyncer] Download data from cloud database success and no more data need to be downloaded"); return -E_QUERY_END; @@ -1579,52 +1426,30 @@ int CloudSyncer::QueryCloudData(const std::string &tableName, std::string &cloud return ret; } -int CloudSyncer::CheckParamValid(const std::vector &devices, SyncMode mode) -{ - if (devices.size() != 1) { - LOGE("[CloudSyncer] invalid devices size %zu", devices.size()); - return -E_INVALID_ARGS; - } - for (const auto &dev: devices) { - if (dev.empty() || dev.size() > DBConstant::MAX_DEV_LENGTH) { - LOGE("[CloudSyncer] invalid device, size %zu", dev.size()); - return -E_INVALID_ARGS; - } - } - if (mode >= SyncMode::SYNC_MODE_PUSH_ONLY && mode < SyncMode::SYNC_MODE_CLOUD_MERGE) { - LOGE("[CloudSyncer] not support mode %d", static_cast(mode)); - return -E_NOT_SUPPORT; - } - if (mode < SyncMode::SYNC_MODE_PUSH_ONLY || mode > SyncMode::SYNC_MODE_CLOUD_FORCE_PULL) { - LOGE("[CloudSyncer] invalid mode %d", static_cast(mode)); - return -E_INVALID_ARGS; - } - return E_OK; -} - int CloudSyncer::CheckTaskIdValid(TaskId taskId) { if (closed_) { LOGE("[CloudSyncer] DB is closed."); return -E_DB_CLOSED; } - { - std::lock_guard autoLock(queueLock_); - if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { - LOGE("[CloudSyncer] not found task."); - return -E_INVALID_ARGS; - } - if (cloudTaskInfos_[taskId].errCode != E_OK) { - return cloudTaskInfos_[taskId].errCode; - } + std::lock_guard autoLock(dataLock_); + if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { + LOGE("[CloudSyncer] not found task."); + return -E_INVALID_ARGS; + } + if (cloudTaskInfos_[taskId].pause) { + LOGW("[CloudSyncer] check task %" PRIu64 " was paused!", taskId); + return -E_TASK_PAUSED; + } + if (cloudTaskInfos_[taskId].errCode != E_OK) { + return cloudTaskInfos_[taskId].errCode; } - std::lock_guard autoLock(contextLock_); return currentContext_.currentTaskId == taskId ? E_OK : -E_INVALID_ARGS; } int CloudSyncer::GetCurrentTableName(std::string &tableName) { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (currentContext_.tableName.empty()) { return -E_BUSY; } @@ -1638,61 +1463,61 @@ int CloudSyncer::TryToAddSyncTask(CloudTaskInfo &&taskInfo) LOGW("[CloudSyncer] syncer is closed, should not sync now"); return -E_DB_CLOSED; } - std::lock_guard autoLock(queueLock_); - int errCode = CheckQueueSizeWithNoLock(); + std::lock_guard autoLock(dataLock_); + int errCode = CheckQueueSizeWithNoLock(taskInfo.priorityTask); if (errCode != E_OK) { return errCode; } do { - currentTaskId_++; - } while (currentTaskId_ == 0); - taskInfo.taskId = currentTaskId_; - taskQueue_.push_back(currentTaskId_); - cloudTaskInfos_[currentTaskId_] = taskInfo; - LOGI("[CloudSyncer] Add task ok, taskId %" PRIu64, cloudTaskInfos_[currentTaskId_].taskId); + lastTaskId_++; + } while (lastTaskId_ == 0); + taskInfo.taskId = lastTaskId_; + if (taskInfo.priorityTask) { + priorityTaskQueue_.push_back(lastTaskId_); + } else { + taskQueue_.push_back(lastTaskId_); + } + cloudTaskInfos_[lastTaskId_] = std::move(taskInfo); + LOGI("[CloudSyncer] Add task ok, taskId %" PRIu64, cloudTaskInfos_[lastTaskId_].taskId); return E_OK; } -int CloudSyncer::CheckQueueSizeWithNoLock() +int CloudSyncer::CheckQueueSizeWithNoLock(bool priorityTask) { int32_t limit = queuedManualSyncLimit_; - if (taskQueue_.size() >= static_cast(limit)) { + if (!priorityTask && taskQueue_.size() >= static_cast(limit)) { LOGW("[CloudSyncer] too much sync task"); return -E_BUSY; + } else if (priorityTask && priorityTaskQueue_.size() >= static_cast(limit)) { + LOGW("[CloudSyncer] too much priority sync task"); + return -E_BUSY; } return E_OK; } int CloudSyncer::PrepareSync(TaskId taskId) { - std::vector tableNames; - std::vector devices; - SyncMode mode; - { - std::lock_guard autoLock(queueLock_); - if (closed_ || cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { - LOGW("[CloudSyncer] Abort sync because syncer is closed"); - return -E_DB_CLOSED; - } - tableNames = cloudTaskInfos_[taskId].table; - mode = cloudTaskInfos_[taskId].mode; - devices = cloudTaskInfos_[taskId].devices; + std::lock_guard autoLock(dataLock_); + if (closed_ || cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { + LOGW("[CloudSyncer] Abort sync because syncer is closed"); + return -E_DB_CLOSED; } - { - // check current task is running or not - std::lock_guard autoLock(contextLock_); - if (closed_ || currentContext_.currentTaskId != INVALID_TASK_ID) { - LOGW("[CloudSyncer] Abort sync because syncer is closed or another task is running"); - return -E_DB_CLOSED; - } - currentContext_.currentTaskId = taskId; - currentContext_.notifier = std::make_shared(this); - currentContext_.strategy = StrategyFactory::BuildSyncStrategy(mode); - currentContext_.notifier->Init(tableNames, devices); - LOGI("[CloudSyncer] exec taskId %" PRIu64, taskId); + if (closed_ || currentContext_.currentTaskId != INVALID_TASK_ID) { + LOGW("[CloudSyncer] Abort sync because syncer is closed or another task is running"); + return -E_DB_CLOSED; } - std::lock_guard autoLock(queueLock_); + currentContext_.currentTaskId = taskId; + cloudTaskInfos_[taskId].resume = cloudTaskInfos_[taskId].pause; + cloudTaskInfos_[taskId].pause = false; cloudTaskInfos_[taskId].status = ProcessStatus::PROCESSING; + if (cloudTaskInfos_[taskId].resume) { + currentContext_ = resumeTaskInfos_[taskId].context; + } else { + currentContext_.notifier = std::make_shared(this); + currentContext_.strategy = StrategyFactory::BuildSyncStrategy(cloudTaskInfos_[taskId].mode); + currentContext_.notifier->Init(cloudTaskInfos_[taskId].table, cloudTaskInfos_[taskId].devices); + } + LOGI("[CloudSyncer] exec taskId %" PRIu64, taskId); return E_OK; } @@ -1813,7 +1638,7 @@ void CloudSyncer::HeartBeatFailed(TaskId taskId, int errCode) void CloudSyncer::SetTaskFailed(TaskId taskId, int errCode) { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { return; } @@ -1823,123 +1648,9 @@ void CloudSyncer::SetTaskFailed(TaskId taskId, int errCode) cloudTaskInfos_[taskId].errCode = errCode; } -int CloudSyncer::CheckCloudSyncDataValid(CloudSyncData uploadData, const std::string &tableName, - const int64_t &count, TaskId &taskId) -{ - size_t insRecordLen = uploadData.insData.record.size(); - size_t insExtendLen = uploadData.insData.extend.size(); - size_t updRecordLen = uploadData.updData.record.size(); - size_t updExtendLen = uploadData.updData.extend.size(); - size_t delRecordLen = uploadData.delData.record.size(); - size_t delExtendLen = uploadData.delData.extend.size(); - - bool syncDataValid = (uploadData.tableName == tableName) && - ((insRecordLen > 0 && insExtendLen > 0 && insRecordLen == insExtendLen) || - (updRecordLen > 0 && updExtendLen > 0 && updRecordLen == updExtendLen) || - (delRecordLen > 0 && delExtendLen > 0 && delRecordLen == delExtendLen)); - if (!syncDataValid) { - LOGE("[CloudSyncer] upload data is empty but upload count is not zero or upload table name" - " is not the same as table name of sync data."); - return -E_INTERNAL_ERROR; - } - int64_t syncDataCount = static_cast(insRecordLen) + static_cast(updRecordLen) + - static_cast(delRecordLen); - if (syncDataCount > count) { - LOGE("[CloudSyncer] Size of a batch of sync data is greater than upload data size."); - return -E_INTERNAL_ERROR; - } - - return E_OK; -} - -int CloudSyncer::GetWaterMarkAndUpdateTime(std::vector& extend, Timestamp &waterMark) -{ - for (auto &extendData: extend) { - if (extendData.empty() || extendData.find(CloudDbConstant::MODIFY_FIELD) == extendData.end()) { - LOGE("[CloudSyncer] VBucket is empty or MODIFY_FIELD doesn't exist."); - return -E_INTERNAL_ERROR; - } - if (TYPE_INDEX != extendData.at(CloudDbConstant::MODIFY_FIELD).index()) { - LOGE("[CloudSyncer] VBucket's MODIFY_FIELD doestn't fit int64_t."); - return -E_INTERNAL_ERROR; - } - if (extendData.empty() || extendData.find(CloudDbConstant::CREATE_FIELD) == extendData.end()) { - LOGE("[CloudSyncer] VBucket is empty or MODIFY_FIELD doesn't exist."); - return -E_INTERNAL_ERROR; - } - if (TYPE_INDEX != extendData.at(CloudDbConstant::CREATE_FIELD).index()) { - LOGE("[CloudSyncer] VBucket's MODIFY_FIELD doestn't fit int64_t."); - return -E_INTERNAL_ERROR; - } - waterMark = std::max(int64_t(waterMark), std::get(extendData.at(CloudDbConstant::MODIFY_FIELD))); - int64_t modifyTime = - std::get(extendData.at(CloudDbConstant::MODIFY_FIELD)) / CloudDbConstant::TEN_THOUSAND; - int64_t createTime = - std::get(extendData.at(CloudDbConstant::CREATE_FIELD)) / CloudDbConstant::TEN_THOUSAND; - extendData.insert_or_assign(CloudDbConstant::MODIFY_FIELD, modifyTime); - extendData.insert_or_assign(CloudDbConstant::CREATE_FIELD, createTime); - } - return E_OK; -} - -// After doing a batch upload, we need to use CloudSyncData's maximum timestamp to update the water mark; -int CloudSyncer::UpdateExtendTime(CloudSyncData &uploadData, const int64_t &count, - TaskId taskId, Timestamp &waterMark) -{ - int ret = CheckCloudSyncDataValid(uploadData, uploadData.tableName, count, taskId); - if (ret != E_OK) { - LOGE("[CloudSyncer] Invalid Sync Data when get local water mark."); - return ret; - } - if (!uploadData.insData.extend.empty()) { - if (uploadData.insData.record.size() != uploadData.insData.extend.size()) { - LOGE("[CloudSyncer] Inconsistent size of inserted data."); - return -E_INTERNAL_ERROR; - } - ret = GetWaterMarkAndUpdateTime(uploadData.insData.extend, waterMark); - if (ret != E_OK) { - return ret; - } - } - - if (!uploadData.updData.extend.empty()) { - if (uploadData.updData.record.size() != uploadData.updData.extend.size()) { - LOGE("[CloudSyncer] Inconsistent size of updated data, %d.", -E_INTERNAL_ERROR); - return -E_INTERNAL_ERROR; - } - ret = GetWaterMarkAndUpdateTime(uploadData.updData.extend, waterMark); - if (ret != E_OK) { - return ret; - } - } - - if (!uploadData.delData.extend.empty()) { - if (uploadData.delData.record.size() != uploadData.delData.extend.size()) { - LOGE("[CloudSyncer] Inconsistent size of deleted data, %d.", -E_INTERNAL_ERROR); - return -E_INTERNAL_ERROR; - } - ret = GetWaterMarkAndUpdateTime(uploadData.delData.extend, waterMark); - if (ret != E_OK) { - return ret; - } - } - return E_OK; -} - -void CloudSyncer::ClearCloudSyncData(CloudSyncData &uploadData) -{ - std::vector().swap(uploadData.insData.record); - std::vector().swap(uploadData.insData.extend); - std::vector().swap(uploadData.insData.rowid); - std::vector().swap(uploadData.updData.record); - std::vector().swap(uploadData.updData.extend); - std::vector().swap(uploadData.delData.record); - std::vector().swap(uploadData.delData.extend); -} - int32_t CloudSyncer::GetCloudSyncTaskCount() { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); return taskQueue_.size(); } @@ -1984,25 +1695,17 @@ int CloudSyncer::CleanCloudData(ClearMode mode, const std::vector & return errCode; } -void CloudSyncer::ModifyCloudDataTime(VBucket &data) -{ - // data already check field modify_field and create_field - int64_t modifyTime = std::get(data[CloudDbConstant::MODIFY_FIELD]) * CloudDbConstant::TEN_THOUSAND; - int64_t createTime = std::get(data[CloudDbConstant::CREATE_FIELD]) * CloudDbConstant::TEN_THOUSAND; - data[CloudDbConstant::MODIFY_FIELD] = modifyTime; - data[CloudDbConstant::CREATE_FIELD] = createTime; -} - -void CloudSyncer::UpdateCloudWaterMark(const SyncParam ¶m) +void CloudSyncer::UpdateCloudWaterMark(TaskId taskId, const SyncParam ¶m) { bool isUpdateCloudCursor = true; { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); isUpdateCloudCursor = currentContext_.strategy->JudgeUpdateCursor(); } + isUpdateCloudCursor = isUpdateCloudCursor && !IsPriorityTask(taskId); // use the cursor of the last datum in data set to update cloud water mark if (isUpdateCloudCursor) { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); currentContext_.cloudWaterMarks[param.info.tableName] = param.cloudWaterMark; } } @@ -2012,7 +1715,7 @@ int CloudSyncer::CommitDownloadResult(InnerProcessInfo &info, DownloadCommitList if (commitList.empty()) { return E_OK; } - uint32_t successCount = 0; + uint32_t successCount = 0u; int ret = HandleDownloadResult(info.tableName, commitList, successCount); info.downLoadInfo.failCount += (commitList.size() - successCount); info.downLoadInfo.successCount -= (commitList.size() - successCount); @@ -2033,12 +1736,12 @@ int CloudSyncer::TagStatusByStrategy(bool isExist, SyncParam ¶m, DataInfo &d strategyOpResult = OpType::NOT_HANDLE; // ignore same record with local generate data if (dataInfo.localInfo.logInfo.device.empty() && - !NeedSaveData(dataInfo.localInfo.logInfo, dataInfo.cloudLogInfo)) { + !CloudSyncUtils::NeedSaveData(dataInfo.localInfo.logInfo, dataInfo.cloudLogInfo)) { // not handle same data return E_OK; } { - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); if (!currentContext_.strategy) { LOGE("[CloudSyncer] strategy has not been set when tag status, %d.", -E_INTERNAL_ERROR); return -E_INTERNAL_ERROR; @@ -2068,40 +1771,419 @@ int CloudSyncer::GetLocalInfo(const std::string &tableName, const VBucket &cloud logInfo.logInfo.cloudGid = localLogInfoCache[hashKey].cloudGid; logInfo.logInfo.device = localLogInfoCache[hashKey].device; // delete record should remove local asset info - if ((localLogInfoCache[hashKey].flag & 0x01) == 1) { + if ((localLogInfoCache[hashKey].flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG) { localAssetInfo.clear(); } } return errCode; } -void CloudSyncer::UpdateLocalCache(OpType opType, const LogInfo &cloudInfo, const LogInfo &localInfo, - std::map &localLogInfoCache) +TaskId CloudSyncer::GetNextTaskId() { - // only cloud delete data need records - if ((cloudInfo.flag & 0x01) != 1) { + std::lock_guard autoLock(dataLock_); + if (!priorityTaskQueue_.empty()) { + return priorityTaskQueue_.front(); + } + if (!taskQueue_.empty()) { + return taskQueue_.front(); + } + return INVALID_TASK_ID; +} + +void CloudSyncer::MarkCurrentTaskPausedIfNeed() +{ + std::lock_guard autoLock(dataLock_); + if (currentContext_.currentTaskId == INVALID_TASK_ID) { return; } - LogInfo updateLogInfo; - std::string hashKey(localInfo.hashKey.begin(), localInfo.hashKey.end()); - switch (opType) { - case OpType::DELETE: { - updateLogInfo.flag |= 0x01; - updateLogInfo.timestamp = cloudInfo.timestamp; - updateLogInfo.wTimestamp = cloudInfo.wTimestamp; - updateLogInfo.device = "cloud"; - localLogInfoCache[hashKey] = updateLogInfo; - break; + if (cloudTaskInfos_.find(currentContext_.currentTaskId) == cloudTaskInfos_.end()) { + return; + } + if (!cloudTaskInfos_[currentContext_.currentTaskId].priorityTask) { + cloudTaskInfos_[currentContext_.currentTaskId].pause = true; + LOGD("[CloudSyncer] Mark taskId %" PRIu64 " paused success", currentContext_.currentTaskId); + } +} + +void CloudSyncer::SetCurrentTaskFailedWithoutLock(int errCode) +{ + if (currentContext_.currentTaskId == INVALID_TASK_ID) { + return; + } + cloudTaskInfos_[currentContext_.currentTaskId].errCode = errCode; +} + +int CloudSyncer::LockCloudIfNeed(TaskId taskId) +{ + { + std::lock_guard autoLock(dataLock_); + if (currentContext_.locker != nullptr) { + LOGD("[CloudSyncer] lock exist"); + return E_OK; } - case OpType::CLEAR_GID: - case OpType::UPDATE_TIMESTAMP: { - updateLogInfo = localInfo; - updateLogInfo.cloudGid.clear(); - localLogInfoCache[hashKey] = updateLogInfo; - break; + } + std::shared_ptr locker = nullptr; + int errCode = CloudLocker::BuildCloudLock([taskId, this]() { + return LockCloud(taskId); + }, [this]() { + int unlockCode = UnlockCloud(); + if (unlockCode != E_OK) { + SetCurrentTaskFailedWithoutLock(unlockCode); } - default: - break; + }, locker); + { + std::lock_guard autoLock(dataLock_); + currentContext_.locker = locker; + } + return errCode; +} + +void CloudSyncer::UnlockIfNeed() +{ + std::lock_guard autoLock(dataLock_); + if ((cloudTaskInfos_[currentContext_.currentTaskId].priorityTask && priorityTaskQueue_.size() > 1) || + (!cloudTaskInfos_[currentContext_.currentTaskId].priorityTask && !priorityTaskQueue_.empty())) { + LOGD("[CloudSyncer] don't unlock because exist priority task"); + return; + } + if (currentContext_.locker == nullptr) { + LOGW("[CloudSyncer] locker is nullptr when unlock it"); // should not happen + } + currentContext_.locker = nullptr; +} + +void CloudSyncer::ClearCurrentContextWithoutLock() +{ + currentContext_.currentTaskId = INVALID_TASK_ID; + currentContext_.notifier = nullptr; + currentContext_.strategy = nullptr; + currentContext_.tableName.clear(); + currentContext_.assetDownloadList.clear(); + currentContext_.assetFields.clear(); + currentContext_.assetsInfo.clear(); + currentContext_.cloudWaterMarks.clear(); +} + +void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) +{ + std::shared_ptr notifier = nullptr; + CloudTaskInfo info; + { + // clear current context + std::lock_guard autoLock(dataLock_); + notifier = currentContext_.notifier; + ClearCurrentContextWithoutLock(); + if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { // should not happen + LOGW("[CloudSyncer] taskId %" PRIu64 " has been finished!", taskId); + contextCv_.notify_one(); + return; + } + info = std::move(cloudTaskInfos_[taskId]); + cloudTaskInfos_.erase(taskId); + resumeTaskInfos_.erase(taskId); + } + contextCv_.notify_one(); + if (info.errCode == E_OK) { + info.errCode = errCode; + } + LOGI("[CloudSyncer] finished taskId %" PRIu64 " errCode %d", taskId, info.errCode); + info.status = ProcessStatus::FINISHED; + if (notifier != nullptr) { + notifier->NotifyProcess(info, {}, true); + } +} + +int CloudSyncer::DownloadOneBatch(TaskId taskId, SyncParam ¶m) +{ + int ret = CheckTaskIdValid(taskId); + if (ret != E_OK) { + return ret; + } + bool abort = false; + ret = DownloadDataFromCloud(taskId, param, abort); + if (abort) { + return ret; + } + // Save data in transaction, update cloud water mark, notify process and changed data + ret = SaveDataNotifyProcess(taskId, param); + if (ret == -E_TASK_PAUSED) { + return ret; + } + if (ret != E_OK) { + std::lock_guard autoLock(dataLock_); + param.info.tableStatus = ProcessStatus::FINISHED; + currentContext_.notifier->UpdateProcess(param.info); + return ret; + } + (void)NotifyInDownload(taskId, param); + return ret; +} + +int CloudSyncer::DownloadOneAssetRecord(const std::set &dupHashKeySet, const DownloadList &downloadList, + DownloadItem &downloadItem, InnerProcessInfo &info, ChangedData &changedAssets) +{ + std::map downloadAssets(downloadItem.assets); + CloudStorageUtils::EraseNoChangeAsset(downloadAssets); + if (downloadAssets.empty()) { // Download data (include deleting) + return E_OK; + } + int errorCode = cloudDB_.Download(info.tableName, downloadItem.gid, downloadItem.prefix, downloadAssets); + if (errorCode == -E_NOT_SET) { + return -E_NOT_SET; + } + if (errorCode != E_OK) { + info.downLoadInfo.failCount += 1; + info.downLoadInfo.successCount -= 1; + } + if (dupHashKeySet.find(downloadItem.hashKey) == dupHashKeySet.end()) { + changedAssets.primaryData[CloudSyncUtils::OpTypeToChangeType(downloadItem.strategy)].push_back( + downloadItem.primaryKeyValList); + } else if (downloadItem.strategy == OpType::INSERT) { + changedAssets.primaryData[ChangeType::OP_UPDATE].push_back(downloadItem.primaryKeyValList); + } + // If the assets are DELETE, needn't fill back cloud assets. + if (downloadItem.strategy == OpType::DELETE) { + return E_OK; + } + CloudStorageUtils::MergeDownloadAsset(downloadAssets, downloadItem.assets); + return errorCode; +} + +int CloudSyncer::GetSyncParamForDownload(TaskId taskId, SyncParam ¶m) +{ + if (IsCurrentTableResume(taskId, false)) { + std::lock_guard autoLock(dataLock_); + if (resumeTaskInfos_[taskId].syncParam.tableName == currentContext_.tableName) { + param = resumeTaskInfos_[taskId].syncParam; + LOGD("[CloudSyncer] Get sync param from cache"); + return E_OK; + } + } + int ret = GetCurrentTableName(param.tableName); + if (ret != E_OK) { + LOGE("[CloudSyncer] Invalid table name for syncing: %d", ret); + return ret; + } + param.info.tableName = param.tableName; + std::vector assetFields; + // only no primary key and composite primary key contains rowid. + ret = storageProxy_->GetPrimaryColNamesWithAssetsFields(param.tableName, param.pkColNames, assetFields); + if (ret != E_OK) { + LOGE("[CloudSyncer] Cannot get primary column names: %d", ret); + return ret; + } + { + std::lock_guard autoLock(dataLock_); + currentContext_.assetFields[currentContext_.tableName] = assetFields; + } + param.isSinglePrimaryKey = CloudSyncUtils::IsSinglePrimaryKey(param.pkColNames); + if (!IsModeForcePull(taskId) && !IsPriorityTask(taskId)) { + ret = storageProxy_->GetCloudWaterMark(param.tableName, param.cloudWaterMark); + if (ret != E_OK) { + LOGE("[CloudSyncer] Cannot get cloud water level from cloud meta data: %d.", ret); + } + } + return ret; +} + +bool CloudSyncer::IsCurrentTableResume(TaskId taskId, bool upload) +{ + std::lock_guard autoLock(dataLock_); + if (!cloudTaskInfos_[taskId].resume) { + return false; + } + if (currentContext_.tableName != resumeTaskInfos_[taskId].context.tableName) { + return false; + } + return upload == resumeTaskInfos_[taskId].upload; +} + +int CloudSyncer::DownloadDataFromCloud(TaskId taskId, SyncParam ¶m, bool &abort) +{ + if (IsCurrentTableResume(taskId, false)) { + std::lock_guard autoLock(dataLock_); + if (resumeTaskInfos_[taskId].skipQuery) { + param.isLastBatch = resumeTaskInfos_[taskId].syncParam.isLastBatch; + LOGD("[CloudSyncer] skip query"); + return E_OK; + } + } + // Get cloud data after cloud water mark + param.info.tableStatus = ProcessStatus::PROCESSING; + param.downloadData = {}; + int ret = QueryCloudData(taskId, param.info.tableName, param.cloudWaterMark, param.downloadData); + if (ret == -E_QUERY_END) { + // Won't break here since downloadData may not be null + param.isLastBatch = true; + } else if (ret != E_OK) { + std::lock_guard autoLock(dataLock_); + param.info.tableStatus = ProcessStatus::FINISHED; + currentContext_.notifier->UpdateProcess(param.info); + abort = true; + return ret; + } + if (param.downloadData.data.empty()) { + if (ret == E_OK) { + LOGD("[CloudSyncer] try to query cloud data use increment water mark"); + UpdateCloudWaterMark(taskId, param); + } + NotifyInEmptyDownload(taskId, param.info); + abort = true; + } + return E_OK; +} + +size_t CloudSyncer::GetDownloadAssetIndex(TaskId taskId) +{ + size_t index = 0u; + std::lock_guard autoLock(dataLock_); + if (resumeTaskInfos_[taskId].lastDownloadIndex != 0u) { + index = resumeTaskInfos_[taskId].lastDownloadIndex; + resumeTaskInfos_[taskId].lastDownloadIndex = 0u; + } + return index; +} + +size_t CloudSyncer::GetStartTableIndex(TaskId taskId, bool upload) +{ + std::lock_guard autoLock(dataLock_); + if (!cloudTaskInfos_[taskId].resume) { + return 0u; + } + if (upload != resumeTaskInfos_[taskId].upload) { + return upload ? 0u : cloudTaskInfos_[taskId].table.size(); + } + for (size_t i = 0; i < cloudTaskInfos_[taskId].table.size(); ++i) { + if (resumeTaskInfos_[taskId].context.tableName == cloudTaskInfos_[taskId].table[i]) { + return i; + } + } + return 0u; +} + +uint32_t CloudSyncer::GetCurrentTableUploadBatchIndex() +{ + std::lock_guard autoLock(dataLock_); + return currentContext_.notifier->GetUploadBatchIndex(currentContext_.tableName); +} + +void CloudSyncer::RecordWaterMark(TaskId taskId, Timestamp waterMark) +{ + std::lock_guard autoLock(dataLock_); + resumeTaskInfos_[taskId].lastLocalWatermark = waterMark; +} + +Timestamp CloudSyncer::GetResumeWaterMark(TaskId taskId) +{ + std::lock_guard autoLock(dataLock_); + return resumeTaskInfos_[taskId].lastLocalWatermark; +} + +void CloudSyncer::ReloadWaterMarkIfNeed(TaskId taskId, WaterMark &waterMark) +{ + Timestamp cacheWaterMark = GetResumeWaterMark(taskId); + waterMark = cacheWaterMark == 0u ? waterMark : cacheWaterMark; + RecordWaterMark(taskId, 0u); +} + +void CloudSyncer::ReloadUploadInfoIfNeed(TaskId taskId, const UploadParam ¶m, InnerProcessInfo &info) +{ + info.upLoadInfo.total = static_cast(param.count); + { + std::lock_guard autoLock(dataLock_); + if (!cloudTaskInfos_[taskId].resume) { + return; + } + } + uint32_t lastSuccessCount = GetLastUploadSuccessCount(info.tableName); + if (lastSuccessCount == 0) { + return; + } + info.upLoadInfo.total += lastSuccessCount; + info.upLoadInfo.successCount += lastSuccessCount; + LOGD("[CloudSyncer] resume upload, last success count %" PRIu32, lastSuccessCount); +} + +uint32_t CloudSyncer::GetLastUploadSuccessCount(const std::string &tableName) +{ + std::lock_guard autoLock(dataLock_); + return currentContext_.notifier->GetLastUploadSuccessCount(tableName); +} + +int CloudSyncer::FillDownloadExtend(TaskId taskId, const std::string &tableName, const std::string &cloudWaterMark, + VBucket &extend) +{ + extend = { + {CloudDbConstant::CURSOR_FIELD, cloudWaterMark} + }; + + QuerySyncObject obj = GetQuerySyncObject(tableName); + if (obj.IsContainQueryNodes()) { + int errCode = GetCloudGid(taskId, tableName, obj); + if (errCode != E_OK) { + LOGE("[CloudSyncer] Failed to get cloud gid when fill extend, %d.", errCode); + return errCode; + } + Bytes bytes; + bytes.resize(obj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT)); + Parcel parcel(bytes.data(), bytes.size()); + errCode = obj.SerializeData(parcel, SOFTWARE_VERSION_CURRENT); + if (errCode != E_OK) { + LOGE("[CloudSyncer] Query serialize failed %d", errCode); + return errCode; + } + extend[CloudDbConstant::TYPE_FIELD] = static_cast(CloudQueryType::QUERY_FIELD); + extend[CloudDbConstant::QUERY_FIELD] = bytes; + } else { + extend[CloudDbConstant::TYPE_FIELD] = static_cast(CloudQueryType::FULL_TABLE); + } + return E_OK; +} + +int CloudSyncer::GetCloudGid(TaskId taskId, const std::string &tableName, QuerySyncObject &obj) +{ + std::vector cloudGid; + bool isCloudForcePush = cloudTaskInfos_[taskId].mode == SYNC_MODE_CLOUD_FORCE_PUSH; + int errCode = storageProxy_->GetCloudGid(obj, isCloudForcePush, cloudGid); + if (errCode != E_OK) { + LOGE("[CloudSyncer] Failed to get cloud gid, %d.", errCode); + } else if (!cloudGid.empty()) { + obj.SetCloudGid(cloudGid); + } + return errCode; +} + +QuerySyncObject CloudSyncer::GetQuerySyncObject(const std::string &tableName) +{ + std::lock_guard autoLock(dataLock_); + for (const auto &item : cloudTaskInfos_[currentContext_.currentTaskId].queryList) { + if (item.GetTableName() == tableName) { + return item; + } + } + LOGW("[CloudSyncer] not found query in cache"); + QuerySyncObject querySyncObject; + querySyncObject.SetTableName(tableName); + return querySyncObject; +} + +CloudSyncer::InnerProcessInfo CloudSyncer::GetInnerProcessInfo(const std::string &tableName, UploadParam &uploadParam) +{ + InnerProcessInfo info; + info.tableName = tableName; + info.tableStatus = ProcessStatus::PROCESSING; + ReloadUploadInfoIfNeed(uploadParam.taskId, uploadParam, info); + return info; +} + +void CloudSyncer::NotifyUploadFailed(int errCode, InnerProcessInfo &info) +{ + LOGE("[CloudSyncer] Failed to do upload, %d", errCode); + info.upLoadInfo.failCount = info.upLoadInfo.total - info.upLoadInfo.successCount; + info.tableStatus = ProcessStatus::FINISHED; + { + std::lock_guard autoLock(dataLock_); + currentContext_.notifier->UpdateProcess(info); } } } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h index 498558018b8c36441882a6c9abe58a4d390b6421..903beb8092fd15a7042429af60700164d1a8d9de 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h @@ -20,22 +20,21 @@ #include #include -#include "cloud_db_proxy.h" #include "cloud/cloud_store_types.h" #include "cloud/cloud_sync_strategy.h" +#include "cloud/icloud_db.h" #include "cloud/icloud_syncer.h" #include "cloud/process_notifier.h" +#include "cloud_db_proxy.h" +#include "cloud_locker.h" #include "data_transformer.h" #include "db_common.h" -#include "cloud/icloud_db.h" #include "ref_object.h" #include "runtime_context.h" #include "storage_proxy.h" #include "store_observer.h" namespace DistributedDB { -using DownloadList = std::vector, Key, - std::vector>>; using DownloadCommitList = std::vector, bool>>; class CloudSyncer : public ICloudSyncer { public: @@ -46,6 +45,8 @@ public: int Sync(const std::vector &devices, SyncMode mode, const std::vector &tables, const SyncProcessCallback &callback, int64_t waitTime); + int Sync(const CloudTaskInfo &taskInfo); + void SetCloudDB(const std::shared_ptr &cloudDB); void SetIAssetLoader(const std::shared_ptr &loader); @@ -63,29 +64,6 @@ public: std::string GetIdentify() const override; protected: - struct DataInfo { - DataInfoWithLog localInfo; - LogInfo cloudLogInfo; - }; - struct WithoutRowIdData { - std::vector insertData = {}; - std::vector> updateData = {}; - std::vector> assetInsertData = {}; - }; - struct SyncParam { - DownloadData downloadData; - ChangedData changedData; - InnerProcessInfo info; - DownloadList assetsDownloadList; - std::string cloudWaterMark; - std::vector pkColNames; - std::set deletePrimaryKeySet; - std::set dupHashKeySet; - std::string tableName; - bool isSinglePrimaryKey; - bool isLastBatch = false; - WithoutRowIdData withoutRowIdData; - }; struct TaskContext { TaskId currentTaskId = 0u; std::string tableName; @@ -97,6 +75,7 @@ protected: // store GID and assets, using in upload procedure std::map>> assetsInfo; std::map cloudWaterMarks; + std::shared_ptr locker; }; struct UploadParam { int64_t count = 0; @@ -112,6 +91,15 @@ protected: Key hashKey; std::vector primaryKeyValList; }; + struct ResumeTaskInfo { + TaskContext context; + SyncParam syncParam; + bool upload = false; // task pause when upload + bool skipQuery = false; // task should skip query now + size_t lastDownloadIndex = 0u; + Timestamp lastLocalWatermark = 0u; + int downloadStatus = E_OK; + }; int TriggerSync(); @@ -123,7 +111,7 @@ protected: int DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUpload); - void DoFinished(TaskId taskId, int errCode, const InnerProcessInfo &processInfo); + void DoFinished(TaskId taskId, int errCode); virtual int DoDownload(CloudSyncer::TaskId taskId); @@ -137,18 +125,6 @@ protected: int DoBatchUpload(CloudSyncData &uploadData, UploadParam &uploadParam, InnerProcessInfo &innerProcessInfo); - int CheckCloudSyncDataValid(CloudSyncData uploadData, const std::string &tableName, const int64_t &count, - TaskId &taskId); - - static bool CheckCloudSyncDataEmpty(const CloudSyncData &uploadData); - - int GetWaterMarkAndUpdateTime(std::vector& extend, Timestamp &waterMark); - - int UpdateExtendTime(CloudSyncData &uploadData, const int64_t &count, TaskId taskId, - Timestamp &waterMark); - - void ClearCloudSyncData(CloudSyncData &uploadData); - int PreProcessBatchUpload(TaskId taskId, const InnerProcessInfo &innerProcessInfo, CloudSyncData &uploadData, Timestamp &localMark); @@ -162,11 +138,14 @@ protected: bool IsModeForcePull(const TaskId taskId); + bool IsPriorityTask(TaskId taskId); + int DoUploadInner(const std::string &tableName, UploadParam &uploadParam); int PreHandleData(VBucket &datum, const std::vector &pkColNames); - int QueryCloudData(const std::string &tableName, std::string &cloudWaterMark, DownloadData &downloadData); + int QueryCloudData(TaskId taskId, const std::string &tableName, std::string &cloudWaterMark, + DownloadData &downloadData); int CheckTaskIdValid(TaskId taskId); @@ -174,7 +153,7 @@ protected: int TryToAddSyncTask(CloudTaskInfo &&taskInfo); - int CheckQueueSizeWithNoLock(); + int CheckQueueSizeWithNoLock(bool priorityTask); int PrepareSync(TaskId taskId); @@ -203,10 +182,7 @@ protected: int SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam ¶m); - int FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, - size_t &delIdx); - - int SaveChangedData(SyncParam ¶m, int dataIndex, const DataInfo &dataInfo, + int SaveChangedData(SyncParam ¶m, size_t dataIndex, const DataInfo &dataInfo, std::vector> &deletedList); int SaveDataNotifyProcess(CloudSyncer::TaskId taskId, SyncParam ¶m); @@ -224,7 +200,8 @@ protected: int TagStatus(bool isExist, SyncParam ¶m, size_t idx, DataInfo &dataInfo, VBucket &localAssetInfo); - int HandleTagAssets(const Key &hashKey, size_t idx, SyncParam ¶m, DataInfo &dataInfo, VBucket &localAssetInfo); + int HandleTagAssets(const Key &hashKey, const DataInfo &dataInfo, size_t idx, SyncParam ¶m, + VBucket &localAssetInfo); int TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam ¶m, DataInfo &dataInfo, VBucket &localAssetInfo); @@ -235,18 +212,21 @@ protected: int HandleDownloadResult(const std::string &tableName, DownloadCommitList &commitList, uint32_t &successCount); + int FillDownloadExtend(TaskId taskId, const std::string &tableName, const std::string &cloudWaterMark, + VBucket &extend); + + int GetCloudGid(TaskId taskId, const std::string &tableName, QuerySyncObject &obj); + int DownloadAssets(InnerProcessInfo &info, const std::vector &pKColNames, const std::set &dupHashKeySet, ChangedData &changedAssets); - int CloudDbDownloadAssets(InnerProcessInfo &info, const DownloadList &downloadList, + int CloudDbDownloadAssets(TaskId taskId, InnerProcessInfo &info, const DownloadList &downloadList, const std::set &dupHashKeySet, ChangedData &changedAssets); void GetDownloadItem(const DownloadList &downloadList, size_t i, DownloadItem &downloadItem); bool IsDataContainAssets(); - void ModifyCloudDataTime(VBucket &data); - int SaveCloudWaterMark(const TableName &tableName); bool IsDataContainDuplicateAsset(const std::vector &assetFields, VBucket &data); @@ -255,14 +235,12 @@ protected: void WaitAllSyncCallbackTaskFinish(); - void UpdateCloudWaterMark(const SyncParam ¶m); + void UpdateCloudWaterMark(TaskId taskId, const SyncParam ¶m); int TagStatusByStrategy(bool isExist, SyncParam ¶m, DataInfo &dataInfo, OpType &strategyOpResult); int CommitDownloadResult(InnerProcessInfo &info, DownloadCommitList &commitList); - static int CheckParamValid(const std::vector &devices, SyncMode mode); - void ClearWithoutData(SyncParam ¶m); void ModifyFieldNameToLower(VBucket &data); @@ -270,15 +248,60 @@ protected: int GetLocalInfo(const std::string &tableName, const VBucket &cloudData, DataInfoWithLog &logInfo, std::map &localLogInfoCache, VBucket &localAssetInfo); - void UpdateLocalCache(OpType opType, const LogInfo &cloudInfo, - const LogInfo &localInfo, std::map &localLogInfoCache); + TaskId GetNextTaskId(); + + void MarkCurrentTaskPausedIfNeed(); - std::mutex queueLock_; - TaskId currentTaskId_; + void SetCurrentTaskFailedWithoutLock(int errCode); + + int LockCloudIfNeed(TaskId taskId); + + void UnlockIfNeed(); + + void ClearCurrentContextWithoutLock(); + + void ClearContextAndNotify(TaskId taskId, int errCode); + + int DownloadOneBatch(TaskId taskId, SyncParam ¶m); + + int DownloadOneAssetRecord(const std::set &dupHashKeySet, const DownloadList &downloadList, + DownloadItem &downloadItem, InnerProcessInfo &info, ChangedData &changedAssets); + + int GetSyncParamForDownload(TaskId taskId, SyncParam ¶m); + + bool IsCurrentTableResume(TaskId taskId, bool upload); + + int DownloadDataFromCloud(TaskId taskId, SyncParam ¶m, bool &abort); + + size_t GetDownloadAssetIndex(TaskId taskId); + + size_t GetStartTableIndex(TaskId taskId, bool upload); + + uint32_t GetCurrentTableUploadBatchIndex(); + + void RecordWaterMark(TaskId taskId, Timestamp waterMark); + + Timestamp GetResumeWaterMark(TaskId taskId); + + void ReloadWaterMarkIfNeed(TaskId taskId, WaterMark &waterMark); + + void ReloadUploadInfoIfNeed(TaskId taskId, const UploadParam ¶m, InnerProcessInfo &info); + + uint32_t GetLastUploadSuccessCount(const std::string &tableName); + + QuerySyncObject GetQuerySyncObject(const std::string &tableName); + + InnerProcessInfo GetInnerProcessInfo(const std::string &tableName, UploadParam &uploadParam); + + void NotifyUploadFailed(int errCode, InnerProcessInfo &info); + + std::mutex dataLock_; + TaskId lastTaskId_; std::list taskQueue_; + std::list priorityTaskQueue_; std::map cloudTaskInfos_; + std::map resumeTaskInfos_; - std::mutex contextLock_; TaskContext currentContext_; std::condition_variable contextCv_; std::mutex syncMutex_; // Clean Cloud Data and Sync are mutually exclusive @@ -301,6 +324,11 @@ protected: int32_t syncCallbackCount_; std::string id_; + + static constexpr const TaskId INVALID_TASK_ID = 0u; + static constexpr const int MAX_HEARTBEAT_FAILED_LIMIT = 2; + static constexpr const int HEARTBEAT_PERIOD = 3; + static constexpr const int MAX_DOWNLOAD_COMMIT_LIMIT = 1; }; } #endif // CLOUD_SYNCER_H diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h index 850138d48910f8d86077a9f26c6092c29afb9024..577f4461b35258f507106b0c57938281ba8d79cd 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h @@ -14,21 +14,31 @@ */ #ifndef I_CLOUD_SYNCER_H #define I_CLOUD_SYNCER_H +#include +#include #include "cloud/cloud_store_types.h" +#include "icloud_sync_storage_interface.h" +#include "query_sync_object.h" #include "ref_object.h" namespace DistributedDB { +using DownloadList = std::vector, Key, + std::vector>>; class ICloudSyncer : public virtual RefObject { public: using TaskId = uint64_t; struct CloudTaskInfo { + bool priorityTask = false; + bool pause = false; + bool resume = false; SyncMode mode = SyncMode::SYNC_MODE_PUSH_ONLY; ProcessStatus status = ProcessStatus::PREPARED; int errCode = 0; TaskId taskId = 0u; - std::vector table; - SyncProcessCallback callback; int64_t timeout = 0; + SyncProcessCallback callback; + std::vector table; std::vector devices; + std::vector queryList; }; struct InnerProcessInfo { @@ -38,6 +48,32 @@ public: Info upLoadInfo; }; + struct WithoutRowIdData { + std::vector insertData = {}; + std::vector> updateData = {}; + std::vector> assetInsertData = {}; + }; + + struct SyncParam { + DownloadData downloadData; + ChangedData changedData; + InnerProcessInfo info; + DownloadList assetsDownloadList; + std::string cloudWaterMark; + std::vector pkColNames; + std::set deletePrimaryKeySet; + std::set dupHashKeySet; + std::string tableName; + bool isSinglePrimaryKey = false; + bool isLastBatch = false; + WithoutRowIdData withoutRowIdData; + }; + + struct DataInfo { + DataInfoWithLog localInfo; + LogInfo cloudLogInfo; + }; + virtual void IncSyncCallbackTaskCount() = 0; virtual void DecSyncCallbackTaskCount() = 0; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp index 668c33d2f14431419730d7cbfc781309d2de8c2d..c28a05ec8d3dc4b90d775910972eb9824eb98131 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp @@ -92,6 +92,7 @@ void ProcessNotifier::NotifyProcess(const ICloudSyncer::CloudTaskInfo &taskInfo, } ICloudSyncer *syncer = syncer_; if (syncer == nullptr) { + LOGW("[ProcessNotifier] cancel notify because syncer is nullptr"); return; // should not happen } RefObject::IncObjRef(syncer); @@ -113,4 +114,22 @@ std::vector ProcessNotifier::GetDevices() const { return devices_; } + +uint32_t ProcessNotifier::GetUploadBatchIndex(const std::string &tableName) const +{ + std::lock_guard autoLock(processMutex_); + if (syncProcess_.tableProcess.find(tableName) == syncProcess_.tableProcess.end()) { + return 0u; + } + return syncProcess_.tableProcess.at(tableName).upLoadInfo.batchIndex; +} + +uint32_t ProcessNotifier::GetLastUploadSuccessCount(const std::string &tableName) const +{ + std::lock_guard autoLock(processMutex_); + if (syncProcess_.tableProcess.find(tableName) == syncProcess_.tableProcess.end()) { + return 0u; + } + return syncProcess_.tableProcess.at(tableName).upLoadInfo.successCount; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h index 326d8ad59a7ac57dd68f1482787a548f4c28dcc2..5a70db4c8644cca10b65b44195022761fe4b9ab6 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h @@ -30,8 +30,12 @@ public: bool notifyWhenError = false); std::vector GetDevices() const; + + uint32_t GetUploadBatchIndex(const std::string &tableName) const; + + uint32_t GetLastUploadSuccessCount(const std::string &tableName) const; protected: - std::mutex processMutex_; + mutable std::mutex processMutex_; SyncProcess syncProcess_; std::vector devices_; ICloudSyncer *syncer_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp index c731634623f3c266543facb2d43b33adeffbcb13..34cb9a228c02980496e275218f24a200ead866b8 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/multi_ver_sync_state_machine.cpp @@ -312,6 +312,7 @@ void MultiVerSyncStateMachine::SendNotifyPacket(uint32_t sessionId, uint32_t seq void MultiVerSyncStateMachine::CommErrAbort(uint32_t sessionId) { + (void)sessionId; std::lock_guard lock(stateMachineLock_); Abort(); RefObject::DecObjRef(context_); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.cpp index 999bb0a4722b82e8865180224ece6d3502c9b5b6..3681a7900f4e110e09a335590e9a5d54873d5143 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.cpp @@ -21,13 +21,6 @@ namespace { constexpr uint8_t ACK_FLAG_LAST_ACK = 1u; constexpr uint8_t ACK_FLAG_SECURITY_OPTION = 2u; } -RemoteExecutorRequestPacket::RemoteExecutorRequestPacket() -{ -} - -RemoteExecutorRequestPacket::~RemoteExecutorRequestPacket() -{ -} uint32_t RemoteExecutorRequestPacket::GetVersion() const { @@ -109,12 +102,14 @@ int RemoteExecutorRequestPacket::Serialization(Parcel &parcel) const return -E_INVALID_ARGS; } if (extraConditions_.size() > DBConstant::MAX_CONDITION_COUNT) { + LOGE("[RemoteExecutorRequestPacket] Serialization failed with too much condition"); return -E_INVALID_ARGS; } parcel.WriteUInt32(static_cast(extraConditions_.size())); for (const auto &entry : extraConditions_) { if (entry.first.length() > DBConstant::MAX_CONDITION_KEY_LEN || entry.second.length() > DBConstant::MAX_CONDITION_VALUE_LEN) { + LOGE("[RemoteExecutorRequestPacket] Serialization failed with too long key or value"); return -E_INVALID_ARGS; } parcel.WriteString(entry.first); @@ -202,14 +197,6 @@ void RemoteExecutorRequestPacket::Release(RemoteExecutorRequestPacket *&packet) packet = nullptr; } -RemoteExecutorAckPacket::RemoteExecutorAckPacket() -{ -} - -RemoteExecutorAckPacket::~RemoteExecutorAckPacket() -{ -} - uint32_t RemoteExecutorAckPacket::GetVersion() const { return version_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.h b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.h index 5d25262cc296757adb0a383bfe59a15f9bbebae4..a80c1f8eae2986714495f0f7f0378b7d16c4058d 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor_packet.h @@ -26,8 +26,8 @@ namespace DistributedDB { class RemoteExecutorRequestPacket : public ISyncPacket { public: - RemoteExecutorRequestPacket(); - ~RemoteExecutorRequestPacket() override; + RemoteExecutorRequestPacket() = default; + ~RemoteExecutorRequestPacket() override = default; uint32_t GetVersion() const; @@ -81,9 +81,9 @@ private: class RemoteExecutorAckPacket : public ISyncPacket { public: - RemoteExecutorAckPacket(); + RemoteExecutorAckPacket() = default; - ~RemoteExecutorAckPacket() override; + ~RemoteExecutorAckPacket() override = default; uint32_t GetVersion() const; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp index 99ac222651eeeb21802ad502084bbbf492ddbfbc..15bb3ea08474128f53d03843f4dd12fa589d0ea4 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp @@ -261,6 +261,8 @@ int SingleVerDataSync::GetDataWithPerformanceRecord(SingleVerSyncTaskContext *co if (performance != nullptr) { performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_READ_DATA); } + // start a watch dog before get data + // it will send ack util get data finished context->StartFeedDogForGetData(context->GetResponseSessionId()); int errCode = GetData(context, packetSize, outData); context->StopFeedDogForGetData(); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp index 051a75d7f3c3c6478fbe606808e668e0cd5652b2..6a97af2065df24f5741f08c9e079ce011a58f474 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync_utils.cpp @@ -213,7 +213,7 @@ bool SingleVerDataSyncUtils::CheckPermitReceiveData(const SingleVerSyncTaskConte // it will send option with not set rather than not support when remote is memory db bool memory = storage->GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false); if (memory) { - LOGE("[DataSync] skip check receive data because local is memory db"); + LOGI("[DataSync] skip check receive data because local is memory db"); return true; } SecurityOption remoteSecOption = context->GetRemoteSeccurityOption(); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp index f7dbfca0f14c0b3319d0272f02ea15b0f1b45ee0..1d05a41b9d8a485dcb8eb18f96726a27315376d4 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_serialize_manager.cpp @@ -194,9 +194,8 @@ uint32_t SingleVerSerializeManager::CalculateControlLen(const Message *inMsg) int SingleVerSerializeManager::RegisterTransformFunc() { - int errCode = RegisterCommunicatorTransformFunc(); RegisterInnerTransformFunc(); - return errCode; + return RegisterCommunicatorTransformFunc(); } int SingleVerSerializeManager::DataPacketSyncerPartSerialization(Parcel &parcel, const DataRequestPacket *packet) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp index 1c1b651ded48a0893303c8d7a3763b4036001658..c63e6f7404eb710b3d3d6aaa59384aa8f36de75e 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp @@ -151,6 +151,7 @@ int SyncEngine::Close() if (executor != nullptr) { executor->Close(); RefObject::DecObjRef(executor); + executor = nullptr; } ClearInnerResource(); LOGI("[SyncEngine] SyncEngine closed!"); @@ -512,17 +513,10 @@ int SyncEngine::MessageReciveCallbackInner(const std::string &targetDev, Message LOGE("[SyncEngine] engine is closing, ignore msg"); return -E_BUSY; } - RemoteExecutor *executor = GetAndIncRemoteExector(); - if (inMsg->GetMessageId() == REMOTE_EXECUTE_MESSAGE && executor != nullptr) { - int errCode = executor->ReceiveMessage(targetDev, inMsg); - RefObject::DecObjRef(executor); - DecExecTaskCount(); - return errCode; - } else if (inMsg->GetMessageId() == REMOTE_EXECUTE_MESSAGE) { - DecExecTaskCount(); - return -E_BUSY; + if (inMsg->GetMessageId() == REMOTE_EXECUTE_MESSAGE) { + return HandleRemoteExecutorMsg(targetDev, inMsg); } - RefObject::DecObjRef(executor); + int msgSize = 0; if (!IsSkipCalculateLen(inMsg)) { msgSize = GetMsgSize(inMsg); @@ -824,6 +818,7 @@ void SyncEngine::OfflineHandleByDevice(const std::string &deviceId) if (executor != nullptr) { executor->NotifyDeviceOffline(deviceId); RefObject::DecObjRef(executor); + executor = nullptr; } // db closed or device is offline // clear remote subscribe and trigger @@ -1199,4 +1194,18 @@ void SyncEngine::WaitingExecTaskExist() LOGD("SyncEngine Close with executing task!"); } } + +int SyncEngine::HandleRemoteExecutorMsg(const std::string &targetDev, Message *inMsg) +{ + RemoteExecutor *executor = GetAndIncRemoteExector(); + int errCode = E_OK; + if (executor != nullptr) { + errCode = executor->ReceiveMessage(targetDev, inMsg); + } else { + errCode = -E_BUSY; + } + DecExecTaskCount(); + RefObject::DecObjRef(executor); + return errCode; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h index 9f2d158046e8471d1f76a904be08f7fa19d4f15d..cc71667819aa9a5a2fe52dc5567fba3ec76cf854 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h @@ -205,6 +205,8 @@ private: void WaitingExecTaskExist(); + int HandleRemoteExecutorMsg(const std::string &targetDev, Message *inMsg); + ICommunicator *communicator_; DeviceManager *deviceManager_; std::function onRemoteDataChanged_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp index 71bd609fc6ee3d0b42801771699e636b42553129..7551a49562d5d6fcf4c11f27650b93eebde2deaf 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_task_context.cpp @@ -486,7 +486,6 @@ void SyncTaskContext::CommErrHandlerFunc(int errCode, ISyncTaskContext *context, LOGI("[SyncTaskContext][CommErrHandle] context has been killed"); return; } - // IncObjRef to maker sure context not been killed. after the lock_guard RefObject::IncObjRef(context); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/time_helper.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/time_helper.cpp index 7f395bcbbed921680a55b57a485498a7d1c7887e..21ff5eda7dbc1fc8d901881cc19aae7cc1013f6f 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/time_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/time_helper.cpp @@ -53,6 +53,10 @@ int TimeHelper::GetSysCurrentRawTime(uint64_t &curTime) if (errCode != 0) { return errCode; } + if (curTime > (UINT64_MAX / TO_100_NS)) { + LOGD("curTime is too large %" PRIu64, curTime); + return -E_OUT_OF_DATE; + } curTime *= TO_100_NS; return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn index b4c5937102a0be96067a404b5f5a93c6dd1c3d62..85cfa5abd95f6b52e2b62d042cd95bff344dd954 100644 --- a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn @@ -245,6 +245,7 @@ ohos_source_set("src_file") { "../syncer/src/cloud/cloud_db_proxy.cpp", "../syncer/src/cloud/cloud_force_pull_strategy.cpp", "../syncer/src/cloud/cloud_force_push_strategy.cpp", + "../syncer/src/cloud/cloud_locker.cpp", "../syncer/src/cloud/cloud_merge_strategy.cpp", "../syncer/src/cloud/cloud_sync_tag_assets.cpp", "../syncer/src/cloud/cloud_sync_utils.cpp", @@ -298,6 +299,7 @@ ohos_source_set("src_file") { "unittest/common/common/thread_pool_test_stub.cpp", "unittest/common/interfaces/process_system_api_adapter_impl.cpp", "unittest/common/syncer/cloud/cloud_db_data_utils.cpp", + "unittest/common/syncer/cloud/cloud_db_sync_utils_test.cpp", "unittest/common/syncer/cloud/virtual_asset_loader.cpp", "unittest/common/syncer/cloud/virtual_cloud_data_translate.cpp", "unittest/common/syncer/cloud/virtual_cloud_db.cpp", @@ -457,6 +459,10 @@ distributeddb_unittest("DistributedDBInterfacesRegisterSyncDBTest") { sources = [ "unittest/common/interfaces/distributeddb_interfaces_register_syncdb_test.cpp" ] } +distributeddb_unittest("DistributedDBInterfacesRelationalObserverTest") { + sources = [ "unittest/common/interfaces/distributeddb_interfaces_relational_observer_test.cpp" ] +} + distributeddb_unittest("DistributedDBInterfacesTransactionSyncDBTest") { sources = [ "unittest/common/interfaces/distributeddb_interfaces_transaction_syncdb_test.cpp", @@ -828,6 +834,10 @@ distributeddb_unittest("DistributedDBCloudStrategyTest") { [ "unittest/common/syncer/cloud/distributeddb_cloud_strategy_test.cpp" ] } +distributeddb_unittest("DistributedDBCloudSyncerDownloadAssetsTest") { + sources = [ "unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp" ] +} + distributeddb_unittest("DistributedDBCloudSyncerUploadTest") { sources = [ "unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp", @@ -866,6 +876,14 @@ distributeddb_unittest("DistributedDBCloudCheckSyncTest") { ] } +distributeddb_unittest("DistributedDBCloudTableCompoundPrimaryKeySyncTest") { + sources = [ "unittest/common/syncer/cloud/distributeddb_cloud_table_compound_primary_key_sync_test.cpp" ] +} + +distributeddb_unittest("DistributedDBCloudTableWithoutPrimaryKeySyncTest") { + sources = [ "unittest/common/syncer/cloud/distributeddb_cloud_table_without_primary_key_sync_test.cpp" ] +} + ############################################################################### group("unittest") { testonly = true @@ -886,6 +904,8 @@ group("unittest") { ":DistributedDBCloudSyncerDownloadTest", ":DistributedDBCloudSyncerProgressManagerTest", ":DistributedDBCloudSyncerUploadTest", + ":DistributedDBCloudTableCompoundPrimaryKeySyncTest", + ":DistributedDBCloudTableWithoutPrimaryKeySyncTest", ":DistributedDBCommonTest", ":DistributedDBCommunicatorDeepTest", ":DistributedDBCommunicatorProxyTest", @@ -913,6 +933,7 @@ group("unittest") { ":DistributedDBInterfacesNBUnpublishTest", ":DistributedDBInterfacesQueryDBTest", ":DistributedDBInterfacesRegisterSyncDBTest", + ":DistributedDBInterfacesRelationalObserverTest", ":DistributedDBInterfacesRelationalRoutinesTest", ":DistributedDBInterfacesRelationalSyncTest", ":DistributedDBInterfacesSchemaDatabaseUpgradeTest", diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp index f31f0610bff44069f10e9889c2ffc27eb2a5489f..c917467bbdef69f4165dee55989d320d3fe20514 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp @@ -57,6 +57,7 @@ static const Asset g_cloudAsset = { .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync", .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC" }; +static constexpr const int MOD = 1000; // 1000 is mod class CloudSyncContext { public: void FinishAndNotify() @@ -126,7 +127,7 @@ public: return; } FuzzerData fuzzerData(data, size); - uint32_t len = fuzzerData.GetUInt32(); + uint32_t len = fuzzerData.GetUInt32() % MOD; for (size_t i = 0; i <= size; ++i) { std::string idStr = fuzzerData.GetString(len); errCode = SQLiteUtils::BindTextToStatement(stmt, 1, idStr); @@ -163,7 +164,7 @@ public: return; } FuzzerData fuzzerData(data, size); - uint32_t len = fuzzerData.GetUInt32(); + uint32_t len = fuzzerData.GetUInt32() % MOD; for (size_t i = 0; i <= size; ++i) { std::string idStr = fuzzerData.GetString(len); errCode = SQLiteUtils::BindTextToStatement(stmt, 1, idStr); @@ -317,7 +318,7 @@ public: void InitAssets(const uint8_t* data, size_t size) { FuzzerData fuzzerData(data, size); - uint32_t len = fuzzerData.GetUInt32(); + uint32_t len = fuzzerData.GetUInt32() % MOD; for (size_t i = 0; i <= size; ++i) { std::string nameStr = fuzzerData.GetString(len); localAssets_.push_back(GenAsset(nameStr, std::to_string(data[0]))); diff --git a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp index 5b852fdee94be5ce45aa5ef85a6e98e14a75fddc..c5f3b9d485d238634ded5fe5003f38cf368d2b32 100644 --- a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp @@ -1259,14 +1259,14 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure007, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } status = g_nbObserverDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE | OBSERVER_CHANGES_FOREIGN, &observerSync); if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } @@ -1346,7 +1346,7 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure008, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } @@ -1435,7 +1435,7 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure009, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } @@ -2219,4 +2219,4 @@ HWTEST_F(DistributeddbNbObserverTest, RekeyNbDb002, TestSize.Level1) */ EXPECT_TRUE(g_nbObserverDelegate->Rekey(g_passwd1) == BUSY); } -} \ No newline at end of file +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_thread_pool_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_thread_pool_test.cpp index 340343d6b63a9de2e31d0cc7e6bd2ba586f5f160..560ba2abc8607dc603b1db97285bdbc99e40409b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_thread_pool_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_thread_pool_test.cpp @@ -433,4 +433,52 @@ HWTEST_F(DistributedDBThreadPoolTest, SetTimer006, TestSize.Level1) } watcher->SafeExit(); } + +/** + * @tc.name: TaskPool001 + * @tc.desc: Test TaskPool schedule task + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBThreadPoolTest, TaskPool001, TestSize.Level1) +{ + RuntimeContext::GetInstance()->SetThreadPool(nullptr); + std::mutex dataMutex; + std::condition_variable cv; + int finishedTaskCount = 0; + int errCode = RuntimeContext::GetInstance()->ScheduleTask([&finishedTaskCount, &dataMutex, &cv]() { + std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep 1s + LOGD("exec task ok"); + { + std::lock_guard autoLock(dataMutex); + finishedTaskCount++; + } + cv.notify_one(); + }); + EXPECT_EQ(errCode, E_OK); + constexpr int execTaskCount = 2; + for (int i = 0; i < execTaskCount; ++i) { + errCode = RuntimeContext::GetInstance()->ScheduleQueuedTask("TaskPool", + [i, &finishedTaskCount, &dataMutex, &cv]() { + LOGD("exec task %d", i); + { + std::lock_guard autoLock(dataMutex); + finishedTaskCount++; + } + cv.notify_one(); + }); + EXPECT_EQ(errCode, E_OK); + std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep 1s + } + { + std::unique_lock uniqueLock(dataMutex); + LOGD("begin wait all task finished"); + cv.wait(uniqueLock, [&finishedTaskCount]() { + return finishedTaskCount == execTaskCount + 1; + }); + LOGD("end wait all task finished"); + } + RuntimeContext::GetInstance()->StopTaskPool(); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp index e30771fea47cd6d02d12ea8d7b76d81373b1ee83..5e78232b73aae15e35e251cb8091b35541b3c06f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp @@ -882,7 +882,7 @@ void RelationalStoreObserverUnitTest::ResetToZero() void RelationalStoreObserverUnitTest::ResetCloudSyncToZero() { - cloudCallCount_ = 0; + cloudCallCount_ = 0u; savedChangedData_.clear(); } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp index 2882e40127a6fb6c79d9904c7f505f1d34ad4ec4..4cab82d5ff9c73301147bf4fc65dec350408ffc3 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp @@ -23,8 +23,8 @@ #include "relational_store_manager.h" using namespace testing::ext; -using namespace DistributedDB; -using namespace DistributedDBUnitTest; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; using namespace std; namespace { @@ -39,6 +39,9 @@ constexpr int E_ERROR = 1; const int WAIT_TIME = 1000; // 1000ms constexpr static uint64_t TO_100_NS = 10; // 1us to 100ns const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000; +std::mutex g_mutex; +std::condition_variable g_cv; +bool g_alreadyNotify = false; class DistributedDBCloudInterfacesRelationalExtTest : public testing::Test { public: @@ -46,20 +49,29 @@ public: static void TearDownTestCase(void); void SetUp() override; void TearDown() override; + void CheckTriggerObserverTest002(const std::string &tableName, std::atomic &count); + void ClientObserverFunc(ClientChangedData &clientChangedData) { - LOGD("client observer fired, table: %s", clientChangedData.tableName.c_str()); - triggerTableName_ = clientChangedData.tableName; + for (const auto &tableName : clientChangedData.tableNames) { + LOGD("client observer fired, table: %s", tableName.c_str()); + triggerTableNames_.insert(tableName); + } triggeredCount_++; + std::unique_lock lock(g_mutex); + g_cv.notify_one(); + g_alreadyNotify = true; } void ClientObserverFunc2(ClientChangedData &clientChangedData) { - LOGD("client observer2 fired, table: %s", clientChangedData.tableName.c_str()); triggeredCount2_++; + std::unique_lock lock(g_mutex); + g_cv.notify_one(); + g_alreadyNotify = true; } - std::string triggerTableName_; + std::set triggerTableNames_; int triggeredCount_ = 0; int triggeredCount2_ = 0; }; @@ -85,6 +97,15 @@ void DistributedDBCloudInterfacesRelationalExtTest::TearDown() DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); } +void DistributedDBCloudInterfacesRelationalExtTest::CheckTriggerObserverTest002(const std::string &tableName, + std::atomic &count) +{ + count++; + ASSERT_EQ(triggerTableNames_.size(), 1u); + EXPECT_EQ(*triggerTableNames_.begin(), tableName); + EXPECT_EQ(triggeredCount_, count); +} + static int GetCurrentSysTimeIn100Ns(uint64_t &outTime) { struct timeval rawTime; @@ -121,7 +142,8 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, GetRawSysTimeTest001, Te EXPECT_EQ(sqlite3_close_v2(db), E_OK); } -void PrepareData(const std::string &tableName, bool primaryKeyIsRowId, bool userDefineRowid = true) +void PrepareData(const std::vector &tableNames, bool primaryKeyIsRowId, + DistributedDB::TableSyncType tableSyncType, bool userDefineRowid = true) { /** * @tc.steps:step1. create db, create table. @@ -131,17 +153,18 @@ void PrepareData(const std::string &tableName, bool primaryKeyIsRowId, bool user EXPECT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); std::string sql; - if (primaryKeyIsRowId) { - sql = "create table " + tableName + "(rowid INTEGER primary key, id int, name TEXT);"; - } else { - if (userDefineRowid) { - sql = "create table " + tableName + "(rowid int, id int, name TEXT, PRIMARY KEY(id, name));"; + for (const auto &tableName : tableNames) { + if (primaryKeyIsRowId) { + sql = "create table " + tableName + "(rowid INTEGER primary key, id int, name TEXT);"; } else { - sql = "create table " + tableName + "(id int, name TEXT, PRIMARY KEY(id));"; + if (userDefineRowid) { + sql = "create table " + tableName + "(rowid int, id int, name TEXT, PRIMARY KEY(id));"; + } else { + sql = "create table " + tableName + "(id int, name TEXT, PRIMARY KEY(id));"; + } } + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } - - EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); EXPECT_EQ(sqlite3_close_v2(db), E_OK); /** @@ -152,26 +175,21 @@ void PrepareData(const std::string &tableName, bool primaryKeyIsRowId, bool user 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(tableName, DistributedDB::CLOUD_COOPERATION), OK); + for (const auto &tableName : tableNames) { + EXPECT_EQ(delegate->CreateDistributedTable(tableName, tableSyncType), OK); + } EXPECT_EQ(g_mgr.CloseStore(delegate), OK); delegate = nullptr; } -/** - * @tc.name: InsertTriggerTest001 - * @tc.desc: Test insert trigger in sqlite - * @tc.type: FUNC - * @tc.require: - * @tc.author: zhangshijie - */ -HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, TestSize.Level0) +void InsertTriggerTest(DistributedDB::TableSyncType tableSyncType) { /** * @tc.steps:step1. prepare data. * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, false); + PrepareData({tableName}, false, tableSyncType); /** * @tc.steps:step2. insert data into sync_data. @@ -193,7 +211,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, Te int resultCount = 0; errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount] (sqlite3_stmt *stmt) { - EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id + EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id std::string device = ""; EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK); EXPECT_EQ(device, ""); @@ -215,21 +233,45 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, Te EXPECT_EQ(sqlite3_close_v2(db), E_OK); } +/** + * @tc.name: InsertTriggerTest001 + * @tc.desc: Test insert trigger in sqlite in CLOUD_COOPERATION mode + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, TestSize.Level0) +{ + InsertTriggerTest(DistributedDB::CLOUD_COOPERATION); +} + /** * @tc.name: InsertTriggerTest002 + * @tc.desc: Test insert trigger in sqlite in DEVICE_COOPERATION mode + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, TestSize.Level0) +{ + InsertTriggerTest(DistributedDB::DEVICE_COOPERATION); +} + +/** + * @tc.name: InsertTriggerTest003 * @tc.desc: Test insert trigger in sqlite when use "insert or replace" * @tc.type: FUNC * @tc.require: * @tc.author: zhangshijie */ -HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, TestSize.Level1) +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest003, TestSize.Level1) { /** * @tc.steps:step1. prepare data. * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, false); + PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION); /** * @tc.steps:step2. insert data into sync_data. @@ -255,7 +297,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, Te sql = "select data_key, device, ori_device, flag, cloud_gid from " + DBCommon::GetLogTableName(tableName); int resultCount = 0; int errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [&resultCount, gid] (sqlite3_stmt *stmt) { - EXPECT_EQ(sqlite3_column_int64(stmt, 0), 3); // 3 is row id + EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id std::string device = ""; EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK); EXPECT_EQ(device, ""); @@ -282,7 +324,7 @@ void UpdateTriggerTest(bool primaryKeyIsRowId) * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, primaryKeyIsRowId); + PrepareData({tableName}, primaryKeyIsRowId, DistributedDB::CLOUD_COOPERATION); /** * @tc.steps:step2. insert data into sync_data_tmp. @@ -311,8 +353,14 @@ void UpdateTriggerTest(bool primaryKeyIsRowId) EXPECT_EQ(errCode, E_OK); int resultCount = 0; - errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount] (sqlite3_stmt *stmt) { - EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id + errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount, primaryKeyIsRowId] ( + sqlite3_stmt *stmt) { + if (primaryKeyIsRowId) { + EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id + } else { + EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id + } + EXPECT_EQ(sqlite3_column_int(stmt, 5), 2); // 5 is column index, flag == 2 std::string device = ""; @@ -374,7 +422,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DeleteTriggerTest001, Te * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, true); + PrepareData({tableName}, true, DistributedDB::CLOUD_COOPERATION); /** * @tc.steps:step2. insert data into sync_data. @@ -477,7 +525,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, false, false); + PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false); /** * @tc.steps:step2. register client observer. @@ -495,8 +543,13 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - EXPECT_EQ(triggerTableName_, tableName); - EXPECT_EQ(triggeredCount_, 3); // 3 is observer triggered counts + std::unique_lock lock(g_mutex); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + std::atomic count = 0; // 0 is observer triggered counts + CheckTriggerObserverTest002(tableName, count); /** * @tc.steps:step4. update data, check observer. @@ -504,8 +557,11 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ sql = "update " + tableName + " set name = 'lisi1' where id = 2;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - EXPECT_EQ(triggerTableName_, tableName); - EXPECT_EQ(triggeredCount_, 4); // 4 is observer triggered counts + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + CheckTriggerObserverTest002(tableName, count); /** * @tc.steps:step4. delete data, check observer. @@ -513,8 +569,11 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ sql = "delete from " + tableName + " where id = 3;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - EXPECT_EQ(triggerTableName_, tableName); - EXPECT_EQ(triggeredCount_, 5); // 5 is observer triggered counts + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + CheckTriggerObserverTest002(tableName, count); /** * @tc.steps:step5. register another observer, update data, check observer. @@ -526,6 +585,10 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK); sql = "update " + tableName + " set name = 'lisi2' where id = 2;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; EXPECT_EQ(triggeredCount_, 0); EXPECT_EQ(triggeredCount2_, 1); @@ -590,7 +653,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, * @tc.expected: step1. return ok. */ const std::string tableName = "sync_data"; - PrepareData(tableName, false, false); + PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false); /** * @tc.steps:step2. register client observer. @@ -607,13 +670,18 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, * @tc.expected: step3. check observer ok. */ std::string sql; - int dataCounts = 1000; + int dataCounts = 1000; // 1000 is count of insert options. for (int i = 1; i <= dataCounts; i++) { sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } - - EXPECT_EQ(triggerTableName_, tableName); + std::unique_lock lock(g_mutex); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + ASSERT_EQ(triggerTableNames_.size(), 1u); + EXPECT_EQ(*triggerTableNames_.begin(), tableName); EXPECT_EQ(triggeredCount_, dataCounts); /** @@ -623,7 +691,164 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, triggeredCount_ = 0; sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - EXPECT_EQ(triggeredCount_, 2); // 2 is trigger times, first delete then insert + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert + EXPECT_EQ(UnRegisterClientObserver(db), OK); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); +} + +/** + * @tc.name: TriggerObserverTest005 + * @tc.desc: Test commit and rollback for one table then trigger client observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, TestSize.Level1) +{ + /** + * @tc.steps:step1. prepare data. + * @tc.expected: step1. return ok. + */ + const std::string tableName = "sync_data"; + PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false); + + /** + * @tc.steps:step2. register client observer. + * @tc.expected: step2. return ok. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, + this, std::placeholders::_1); + EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK); + + /** + * @tc.steps:step3. begin transaction and commit. + * @tc.expected: step3. check observer ok. + */ + std::string sql = "begin;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + int dataCounts = 1000; // 1000 is count of insert options. + for (int i = 1; i <= dataCounts; i++) { + sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + } + sql = "commit;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + std::unique_lock lock(g_mutex); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + ASSERT_EQ(triggerTableNames_.size(), 1u); + EXPECT_EQ(*triggerTableNames_.begin(), tableName); + EXPECT_EQ(triggeredCount_, 1); + + /** + * @tc.steps:step4. begin transaction and rollback. + * @tc.expected: step3. check observer ok. + */ + triggerTableNames_.clear(); + triggeredCount_ = 0; + sql = "begin;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + for (int i = dataCounts + 1; i <= 2 * dataCounts; i++) { // 2 is double dataCounts + sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + } + sql = "rollback;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + EXPECT_TRUE(triggerTableNames_.empty()); + EXPECT_EQ(triggeredCount_, 0); + + /** + * @tc.steps:step5. insert or replace, check observer. + * @tc.expected: step5. check observer ok. + */ + triggeredCount_ = 0; + sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert + EXPECT_EQ(UnRegisterClientObserver(db), OK); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); +} + +/** + * @tc.name: TriggerObserverTest006 + * @tc.desc: Test commit and rollback for multi-table then trigger client observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, TestSize.Level1) +{ + /** + * @tc.steps:step1. prepare data. + * @tc.expected: step1. return ok. + */ + const std::string tableName1 = "sync_data1"; + const std::string tableName2 = "sync_data2"; + PrepareData({tableName1, tableName2}, false, DistributedDB::CLOUD_COOPERATION, false); + + /** + * @tc.steps:step2. register client observer. + * @tc.expected: step2. return ok. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, + this, std::placeholders::_1); + EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK); + + /** + * @tc.steps:step3. begin transaction and commit. + * @tc.expected: step3. check observer ok. + */ + std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + std::unique_lock lock(g_mutex); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + ASSERT_EQ(triggerTableNames_.size(), 1u); // 1 is table size + EXPECT_EQ(*triggerTableNames_.begin(), tableName1); + EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count + + /** + * @tc.steps:step4. UnRegisterClientObserver and insert table2. + * @tc.expected: step3. check observer ok. + */ + triggerTableNames_.clear(); + triggeredCount_ = 0; + EXPECT_EQ(UnRegisterClientObserver(db), OK); + sql = "insert into " + tableName2 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + EXPECT_TRUE(triggerTableNames_.empty()); + EXPECT_EQ(triggeredCount_, 0); + + /** + * @tc.steps:step5. RegisterClientObserver again and insert table1, check observer. + * @tc.expected: step5. check observer ok. + */ + EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK); + sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + ASSERT_EQ(triggerTableNames_.size(), 1u); // 1 is table size + EXPECT_EQ(*triggerTableNames_.begin(), tableName1); + EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count EXPECT_EQ(UnRegisterClientObserver(db), OK); EXPECT_EQ(sqlite3_close_v2(db), E_OK); } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp index be28010419af71ad93dd6631851a6e77c7494355..5c529b4d91ebb87c8c26c4c073cbd5fc735d0533 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp @@ -31,6 +31,7 @@ #include "virtual_cloud_data_translate.h" #include "virtual_cloud_db.h" #include "mock_asset_loader.h" +#include "cloud_db_sync_utils_test.h" using namespace testing::ext; using namespace DistributedDB; @@ -224,6 +225,17 @@ namespace { std::this_thread::sleep_for(std::chrono::milliseconds(count)); } + void DeleteCloudTableRecordByGid(int64_t begin, int64_t count) + { + for (int64_t i = begin; i < begin + count; ++i) { + VBucket data; + data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i)); + ASSERT_EQ(g_virtualCloudDb->DeleteByGid(g_tableName1, data), DBStatus::OK); + } + LOGD("delete cloud record worker[primary key]:[cloud%" PRId64 " - cloud%" PRId64")", begin, count); + std::this_thread::sleep_for(std::chrono::milliseconds(count)); + } + void GetCloudDbSchema(DataBaseSchema &dataBaseSchema) { TableSchema tableSchema1 = { @@ -258,6 +270,25 @@ namespace { return 0; } + void CheckCloudTotalCount(std::vector expectCounts) + { + VBucket extend; + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); + for (size_t i = 0; i < g_tables.size(); ++i) { + int64_t realCount = 0; + std::vector data; + g_virtualCloudDb->Query(g_tables[i], extend, data); + for (size_t j = 0; j < data.size(); ++j) { + auto entry = data[j].find(CloudDbConstant::DELETE_FIELD); + if (entry != data[j].end() && std::get(entry->second)) { + continue; + } + realCount++; + } + EXPECT_EQ(realCount, expectCounts[i]); // ExpectCount represents the total amount of cloud data. + } + } + void CheckCloudRecordNum(sqlite3 *&db, std::vector tableList, std::vector countList) { int i = 0; @@ -701,5 +732,78 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudD ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK); CloseDb(); } + +/* + * @tc.name: CleanCloudDataTest005 + * @tc.desc: Test RemoveDeviceData when cloud data is deleted + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest005, TestSize.Level0) +{ + /** + * @tc.steps: step1. cloud and device data is same + * @tc.expected: OK. + */ + int64_t paddingSize = 10; // 10 is padding size + int64_t cloudCount = 10; // 10 is cloud count + InsertCloudTableRecord(0, cloudCount, paddingSize, true); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + + /** + * @tc.steps: step2. cloud delete data and merge + * @tc.expected: OK. + */ + DeleteCloudTableRecordByGid(0, cloudCount); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CheckCloudRecordNum(db, g_tables, {0, 10}); // 10 is cloud record num in table2 log + CheckCloudTotalCount({0, 10}); // // 10 is cloud data num in table2 + + /** + * @tc.steps: step3. removedevicedata FLAG_AND_DATA and check log + * @tc.expected: OK. + */ + std::string device = ""; + ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK); + CheckCleanDataAndLogNum(db, g_tables, 0, {0, 0}); + CloseDb(); +} + +/* + * @tc.name: CleanCloudDataTest006 + * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData before Sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest006, TestSize.Level0) +{ + /** + * @tc.steps: step1. make data: 10 records on local + */ + int64_t paddingSize = 10; + int localCount = 10; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + /** + * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 20 records. + */ + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + LOGW("check 10-10"); + CheckCloudTotalCount({10, 10}); // // 10 is cloud data num in table2 + g_virtualCloudDb->ClearAllData(); + LOGW("check 0-0"); + CheckCloudTotalCount({0, 0}); // // 0 is cloud data num in table2 + /** + * @tc.steps: step3. removedevicedata FLAG_AND_DATA and sync again + * @tc.expected: OK. + */ + std::string device; + ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_ONLY), DBStatus::OK); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + LOGW("check 10-10"); + CheckCloudTotalCount({10, 10}); // // 10 is cloud data num in table2 + CloseDb(); +} } #endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp index 8ee047752c2ca194423b735f81392d3b92852091..0608668c064b9d442f485b5ca54d65b86d5ca919 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp @@ -1210,6 +1210,8 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerPutBatchObserver001, Te */ Key key; EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, observer), OK); + // register same observer twice will return already_set + EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, observer), ALREADY_SET); /** * @tc.steps:step3. Put batch data. * @tc.expected: step3. Returns OK. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_observer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_observer_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8e31c7f3d80088b76e613176d5d768d0ef24824 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_observer_test.cpp @@ -0,0 +1,293 @@ +/* + * 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 + +#include "db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "log_print.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "virtual_relational_ver_sync_db_interface.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + constexpr const char *DB_SUFFIX = ".db"; + constexpr const char *STORE_ID = "Relational_Store_ID"; + std::string g_testDir; + std::string g_dbDir; + std::string g_storePath; + DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID); + RelationalStoreDelegate *g_delegate = nullptr; + + class DistributedDBInterfacesRelationalObserverTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + }; + + void DistributedDBInterfacesRelationalObserverTest::SetUpTestCase(void) + { + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + LOGD("Test dir is %s", g_testDir.c_str()); + g_dbDir = g_testDir + "/"; + g_storePath = g_dbDir + STORE_ID + DB_SUFFIX; + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); + } + + void DistributedDBInterfacesRelationalObserverTest::TearDownTestCase(void) + { + } + + void DistributedDBInterfacesRelationalObserverTest::SetUp(void) + { + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + + DBStatus status = g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(g_delegate, nullptr); + } + + void DistributedDBInterfacesRelationalObserverTest::TearDown(void) + { + EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK); + g_delegate = nullptr; + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); + } + + /** + * @tc.name: RelationalObserverTest001 + * @tc.desc: Test invalid args for register unregister observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshjie + */ + HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest001, TestSize.Level0) + { + EXPECT_EQ(g_delegate->RegisterObserver(nullptr), INVALID_ARGS); + EXPECT_EQ(g_delegate->UnRegisterObserver(nullptr), INVALID_ARGS); + } + + /** + * @tc.name: RelationalObserverTest002 + * @tc.desc: Test register same observer twice + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshjie + */ + HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest002, TestSize.Level0) + { + /** + * @tc.steps:step1. register observer1 twice + * @tc.expected: step1. Return OK for first, return ALREADY_SET for second. + */ + RelationalStoreObserverUnitTest *observer1 = new (std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observer1, nullptr); + EXPECT_EQ(g_delegate->RegisterObserver(observer1), OK); + EXPECT_EQ(g_delegate->RegisterObserver(observer1), ALREADY_SET); + + /** + * @tc.steps:step2. unregister observer1 twice + * @tc.expected: step2. Return OK for first, return NOT_FOUND for second. + */ + EXPECT_EQ(g_delegate->UnRegisterObserver(observer1), OK); + EXPECT_EQ(g_delegate->UnRegisterObserver(observer1), NOT_FOUND); + + /** + * @tc.steps:step3. register observer1 again + * @tc.expected: step3. Return OK. + */ + EXPECT_EQ(g_delegate->RegisterObserver(observer1), OK); + + delete observer1; + observer1 = nullptr; + } + + /** + * @tc.name: RelationalObserverTest003 + * @tc.desc: Test register observer over limit + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshjie + */ + HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest003, TestSize.Level0) + { + /** + * @tc.steps:step1. register DBConstant::MAX_OBSERVER_COUNT + 1 observer + * @tc.expected: step1. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for + * DBConstant::MAX_OBSERVER_COUNT + 1. + */ + RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT + 1] = { nullptr }; + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + observerArr[i] = new (std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observerArr[i], nullptr); + if (i < DBConstant::MAX_OBSERVER_COUNT) { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK); + } else { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS); + } + } + + /** + * @tc.steps:step2. unregister observer1, than register again + * @tc.expected: step2. Return OK + */ + EXPECT_EQ(g_delegate->UnRegisterObserver(observerArr[0]), OK); + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[0]), OK); + + /** + * @tc.steps:step3. call UnRegisterObserver() unregister all observer + * @tc.expected: step3. Return OK + */ + EXPECT_EQ(g_delegate->UnRegisterObserver(), OK); + + /** + * @tc.steps:step4. register DBConstant::MAX_OBSERVER_COUNT + 1 observer + * @tc.expected: step4. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for + * DBConstant::MAX_OBSERVER_COUNT + 1. + */ + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + if (i < DBConstant::MAX_OBSERVER_COUNT) { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK); + } else { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS); + } + } + + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + delete observerArr[i]; + observerArr[i] = nullptr; + } + } + + /** + * @tc.name: RelationalObserverTest004 + * @tc.desc: Test register observer over limit when OpenStore will register one observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshjie + */ + HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest004, TestSize.Level0) + { + /** + * @tc.steps:step1. open store with observer + * @tc.expected: step1. Return OK + */ + RelationalStoreDelegate *delegate = nullptr; + RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observer, nullptr); + RelationalStoreDelegate::Option option; + option.observer = observer; + EXPECT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, option, delegate), OK); + ASSERT_NE(delegate, nullptr); + + /** + * @tc.steps:step2. register DBConstant::MAX_OBSERVER_COUNT observer + * @tc.expected: step2. Return OK for first DBConstant::MAX_OBSERVER_COUNT - 1, return OVER_MAX_LIMITS for + * DBConstant::MAX_OBSERVER_COUNT because already register one observer when open store. + */ + RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT] = { nullptr }; + for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) { + observerArr[i] = new (std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observerArr[i], nullptr); + if (i < DBConstant::MAX_OBSERVER_COUNT - 1) { + EXPECT_EQ(delegate->RegisterObserver(observerArr[i]), OK); + } else { + EXPECT_EQ(delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS); + } + } + + /** + * @tc.steps:step3. close store + * @tc.expected: step3. Return OK + */ + EXPECT_EQ(g_mgr.CloseStore(delegate), OK); + delegate = nullptr; + delete observer; + observer = nullptr; + for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) { + delete observerArr[i]; + observerArr[i] = nullptr; + } + } + + /** + * @tc.name: RelationalObserverTest005 + * @tc.desc: Test register observer with two delegate + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshjie + */ + HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest005, TestSize.Level0) + { + /** + * @tc.steps:step1. register DBConstant::MAX_OBSERVER_COUNT + 1 observer + * @tc.expected: step1. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for + * DBConstant::MAX_OBSERVER_COUNT + 1. + */ + RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT + 1] = {nullptr}; + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + observerArr[i] = new(std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observerArr[i], nullptr); + if (i < DBConstant::MAX_OBSERVER_COUNT) { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK); + } else { + EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS); + } + } + + /** + * @tc.steps:step2. register DBConstant::MAX_OBSERVER_COUNT + 1 observer with another delegate + * @tc.expected: step2. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for + * DBConstant::MAX_OBSERVER_COUNT + 1. + */ + RelationalStoreDelegate *delegate = nullptr; + EXPECT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, {}, delegate), OK); + ASSERT_NE(delegate, nullptr); + RelationalStoreObserverUnitTest *observerArr1[DBConstant::MAX_OBSERVER_COUNT + 1] = {nullptr}; + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + observerArr1[i] = new(std::nothrow) RelationalStoreObserverUnitTest(); + EXPECT_NE(observerArr1[i], nullptr); + if (i < DBConstant::MAX_OBSERVER_COUNT) { + EXPECT_EQ(delegate->RegisterObserver(observerArr1[i]), OK); + } else { + EXPECT_EQ(delegate->RegisterObserver(observerArr1[i]), OVER_MAX_LIMITS); + } + } + + /** + * @tc.steps:step3. close store and delete observer + * @tc.expected: step3. Return OK + */ + EXPECT_EQ(g_mgr.CloseStore(delegate), OK); + delegate = nullptr; + for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) { + delete observerArr[i]; + observerArr[i] = nullptr; + delete observerArr1[i]; + observerArr1[i] = nullptr; + } + } +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp index 4d9e69adbbd39eaf96706b2efb08b2247a04deb3..1eaeb19674b7586d28ef3fa45b31f1bb20c7c80e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp @@ -550,7 +550,7 @@ HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpgradeTriggerTest001, TestS "BEGIN\n" "\t UPDATE naturalbase_rdb_aux_student_1_log SET data_key=-1,timestamp=get_sys_time(0), device=''," " flag=0x03 WHERE hash_key=calc_hash(OLD.'id', 0) AND flag&0x02=0x02;\n" - "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW.rowid, '', '', get_sys_time(0), " + "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW._rowid_, '', '', get_sys_time(0), " "get_last_time(), CASE WHEN (calc_hash(NEW.'id', 0) != calc_hash(NEW.'id', 0)) " \ "THEN 0x02 ELSE 0x22 END, calc_hash(NEW.'id', 0), '');\n" "END"; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index f47f01bdc3187bb95d06ab1abd5da12300c9dbbe..1c02095ec25b0e2238e2261c7c8c3e50359ed9fe 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -1708,7 +1708,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, GetDistributedTableName001, Test * @tc.require: * @tc.author: zhangshjie */ -HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest001, TestSize.Level0) { +HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest001, TestSize.Level0) +{ /** * @tc.steps:step1. Prepare db file * @tc.expected: step1. Return OK. @@ -1749,7 +1750,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest001, T * @tc.require: * @tc.author: zhangshjie */ -HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, TestSize.Level0) { +HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, TestSize.Level0) +{ /** * @tc.steps:step1. Prepare db file * @tc.expected: step1. Return OK. @@ -1821,4 +1823,65 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, T EXPECT_EQ(status, OK); delegate = nullptr; } + +/** + * @tc.name: CreateDistributedTableTest003 + * @tc.desc: Test create distributed table after rename table + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest003, TestSize.Level0) +{ + /** + * @tc.steps:step1. Prepare db file + */ + 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); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + /** + * @tc.steps:step2. open relational store, create distributed table with default mode + */ + 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); + + status = delegate->CreateDistributedTable("t1"); + EXPECT_EQ(status, OK); + /** + * @tc.steps:step3. rename table + */ + db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "alter table t1 rename to t2;"), SQLITE_OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + /** + * @tc.steps:step4. reopen delegate + */ + status = g_mgr.CloseStore(delegate); + EXPECT_EQ(status, OK); + delegate = nullptr; + status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + /** + * @tc.steps:step5. create distributed table and insert data ok + */ + status = delegate->CreateDistributedTable("t2"); + EXPECT_EQ(status, OK); + + db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "insert into t2 values(1, '2');"), SQLITE_OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + /** + * @tc.steps:step6. close store + */ + status = g_mgr.CloseStore(delegate); + EXPECT_EQ(status, OK); + delegate = nullptr; +} } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp index 831183c48f322663d549dc1e2d206708c2a7397d..c870fb959d1d6fc8dd6a02eac2f64ceeaa38dacc 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp @@ -14,12 +14,14 @@ */ #ifdef RELATIONAL_STORE #include +#include "cloud_db_constant.h" #include "cloud_db_types.h" #include "distributeddb_data_generate_unit_test.h" #include "log_print.h" #include "relational_store_delegate.h" #include "relational_store_manager.h" #include "runtime_config.h" +#include "time_helper.h" #include "virtual_asset_loader.h" #include "virtual_cloud_data_translate.h" #include "virtual_cloud_db.h" @@ -36,6 +38,11 @@ const char *g_createSQL = "age INT);"; const int64_t g_syncWaitTime = 60; +const Asset g_cloudAsset = { + .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync", + .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC" +}; + void CreateUserDBAndTable(sqlite3 *&db) { EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); @@ -76,6 +83,9 @@ protected: DataBaseSchema GetSchema(); void CloseDb(); void InsertUserTableRecord(int64_t recordCounts, int64_t begin = 0); + void InsertCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull); + void DeleteUserTableRecord(int64_t id); + void DeleteCloudTableRecord(int64_t gid); std::string testDir_; std::string storePath_; sqlite3 *db_ = nullptr; @@ -170,6 +180,65 @@ void DistributedDBCloudCheckSyncTest::InsertUserTableRecord(int64_t recordCounts } } +void DistributedDBCloudCheckSyncTest::InsertCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, + bool assetIsNull) +{ + std::vector photo(photoSize, 'v'); + std::vector record1; + std::vector extend1; + std::vector record2; + std::vector extend2; + Timestamp now = TimeHelper::GetSysCurrentTime(); + for (int64_t i = begin; i < begin + count; ++i) { + VBucket data; + data.insert_or_assign("id", std::to_string(i)); + data.insert_or_assign("name", "Cloud" + std::to_string(i)); + data.insert_or_assign("height", 166.0); // 166.0 is random double value + data.insert_or_assign("married", false); + data.insert_or_assign("photo", photo); + data.insert_or_assign("age", static_cast(13L)); // 13 is random age + Asset asset = g_cloudAsset; + asset.name = asset.name + std::to_string(i); + assetIsNull ? data.insert_or_assign("assert", Nil()) : data.insert_or_assign("assert", asset); + record1.push_back(data); + VBucket log; + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, static_cast( + now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, static_cast( + now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + extend1.push_back(log); + + std::vector assets; + data.insert_or_assign("height", 180.3); // 180.3 is random double value + for (int64_t j = i; j <= i + 2; j++) { // 2 extra num + asset.name = g_cloudAsset.name + std::to_string(j); + assets.push_back(asset); + } + data.erase("assert"); + data.erase("married"); + assetIsNull ? data.insert_or_assign("asserts", Nil()) : data.insert_or_assign("asserts", assets); + record2.push_back(data); + extend2.push_back(log); + } + ASSERT_EQ(virtualCloudDb_->BatchInsert(tableName_, std::move(record1), extend1), DBStatus::OK); + std::this_thread::sleep_for(std::chrono::milliseconds(count)); +} + +void DistributedDBCloudCheckSyncTest::DeleteUserTableRecord(int64_t id) +{ + ASSERT_NE(db_, nullptr); + string sql = "DELETE FROM " + tableName_ + " WHERE id ='" + std::to_string(id) + "';"; + ASSERT_EQ(SQLiteUtils::ExecuteRawSQL(db_, sql), E_OK); +} + +void DistributedDBCloudCheckSyncTest::DeleteCloudTableRecord(int64_t gid) +{ + VBucket idMap; + idMap.insert_or_assign("#_gid", std::to_string(gid)); + ASSERT_EQ(virtualCloudDb_->DeleteByGid(tableName_, idMap), DBStatus::OK); +} + /** * @tc.name: CloudSyncTest001 * @tc.desc: sync with device sync query @@ -197,5 +266,112 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest001, TestSize.Level0) }); EXPECT_EQ(dataCnt, actualCount); } + +/** + * @tc.name: CloudSyncTest002 + * @tc.desc: sync with same data in one batch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest002, TestSize.Level0) +{ + // prepare data + const int actualCount = 1; + InsertUserTableRecord(actualCount); + // sync twice + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + // cloud delete id=0 and insert id=0 but its gid is 1 + // local delete id=0 + DeleteCloudTableRecord(0); // cloud gid is 0 + InsertCloudTableRecord(0, actualCount, 0, false); // 0 is id + DeleteUserTableRecord(0); // 0 is id + BlockSync(query, delegate_); + bool deleteStatus = true; + EXPECT_EQ(virtualCloudDb_->GetDataStatus("1", deleteStatus), OK); + EXPECT_EQ(deleteStatus, false); + // check local data + int dataCnt = -1; + std::string checkLogSql = "SELECT count(*) FROM " + tableName_; + RelationalTestUtils::ExecSql(db_, checkLogSql, nullptr, [&dataCnt](sqlite3_stmt *stmt) { + dataCnt = sqlite3_column_int(stmt, 0); + return E_OK; + }); + EXPECT_EQ(dataCnt, actualCount); +} + +/** + * @tc.name: CloudSyncObserverTest001 + * @tc.desc: test cloud sync multi observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncObserverTest001, TestSize.Level0) +{ + // prepare data + const int actualCount = 10; + InsertUserTableRecord(actualCount); + + /** + * @tc.steps:step1. open two delegate with two observer. + * @tc.expected: step1. ok. + */ + RelationalStoreDelegate::Option option; + auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(observer1, nullptr); + option.observer = observer1; + RelationalStoreDelegate *delegate1 = nullptr; + EXPECT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1, option, delegate1), DBStatus::OK); + ASSERT_NE(delegate1, nullptr); + + auto observer2 = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(observer2, nullptr); + option.observer = observer2; + RelationalStoreDelegate *delegate2 = nullptr; + EXPECT_EQ(mgr_->OpenStore(storePath_, STORE_ID_1, option, delegate2), DBStatus::OK); + ASSERT_NE(delegate2, nullptr); + + /** + * @tc.steps:step2. insert 1-10 cloud data, start. + * @tc.expected: step2. ok. + */ + InsertCloudTableRecord(0, actualCount, actualCount, false); + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + + /** + * @tc.steps:step3. check observer. + * @tc.expected: step3. ok. + */ + EXPECT_EQ(observer1->GetCloudCallCount(), 1u); + EXPECT_EQ(observer2->GetCloudCallCount(), 1u); + + /** + * @tc.steps:step4. insert 11-20 cloud data, start. + * @tc.expected: step4. ok. + */ + delegate2->UnRegisterObserver(); + observer2->ResetCloudSyncToZero(); + int64_t begin = 11; + InsertCloudTableRecord(begin, actualCount, actualCount, false); + BlockSync(query, delegate_); + + /** + * @tc.steps:step5. check observer. + * @tc.expected: step5. ok. + */ + EXPECT_EQ(observer1->GetCloudCallCount(), 2u); // 2 is observer1 triggered times + EXPECT_EQ(observer2->GetCloudCallCount(), 0u); + + delete observer1; + observer1 = nullptr; + EXPECT_EQ(mgr_->CloseStore(delegate1), DBStatus::OK); + + delete observer2; + observer2 = nullptr; + EXPECT_EQ(mgr_->CloseStore(delegate2), DBStatus::OK); +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp index 6c497bbd1c3b68a6122b9424562a5f7a34bf17b8..4e211c6950c4efcfbef3e5bd562e1c0ebdfab1f1 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp @@ -2294,15 +2294,8 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DownloadAssetTest004, T g_syncProcess = {}; InsertCloudTableRecord(0, count, paddingSize, false); EXPECT_EQ(RelationalTestUtils::ExecSql(db, DROP_INTEGER_PRIMARY_KEY_TABLE_SQL), DBStatus::OK); - EXPECT_EQ(g_delegate->Sync({ DEVICE_CLOUD }, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); - EXPECT_EQ(g_syncProcess.errCode, DBStatus::DB_ERROR); - uint32_t expectTotalCnt = 20u; - EXPECT_NE(g_syncProcess.tableProcess.find(g_tableName2), g_syncProcess.tableProcess.end()); - EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.batchIndex, 1u); - EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.total, expectTotalCnt); - EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.successCount, 0u); - EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.failCount, expectTotalCnt); + EXPECT_EQ(g_delegate->Sync({ DEVICE_CLOUD }, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), + DBStatus::NOT_FOUND); /** * @tc.steps:step3. close db. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_meta_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_meta_data_test.cpp index 72ef9ddfabfe5438e72dd03fa555d2c9a7b3789a..15a927bae40e9834d4f67af4b9e1711b4a433ecb 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_meta_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_meta_data_test.cpp @@ -138,6 +138,7 @@ namespace { void DistributedDBCloudMetaDataTest::TearDown(void) { + RefObject::DecObjRef(g_store); if (g_delegate != nullptr) { EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK); g_delegate = nullptr; @@ -199,5 +200,4 @@ namespace { EXPECT_EQ(g_storageProxy->GetLocalWaterMark(TABLE_NAME_2, retLocalMark), E_OK); EXPECT_EQ(retLocalMark, 0u); } - } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp index 92c8a438fd5b101c5a0f41cc6085613ca454dc43..c8b53608e1be07a803db62fc6e8024483add07d3 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp @@ -460,6 +460,294 @@ namespace { VbucketWithoutPrimaryDataTest(PrimaryKeyType::COMPOSITE_PRIMARY_KEY); } + void SetCloudSchemaForCollate(bool ageIsPrimaryKey) + { + TableSchema tableSchema; + Field field1 = { "name", TYPE_INDEX, true, false }; + Field field2 = { "age", TYPE_INDEX, ageIsPrimaryKey, false }; + tableSchema = { g_tableName, { field1, field2 } }; + + DataBaseSchema dbSchema; + dbSchema.tables = { tableSchema }; + g_cloudStore->SetCloudDbSchema(dbSchema); + } + + void PrimaryKeyCollateTest(const std::string &createSql, const std::string &insertSql, + const std::vector &pkStr, bool ageIsPrimaryKey, int expectCode = E_OK) + { + /** + * @tc.steps:step1. create table. + * @tc.expected: step1. return ok. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), E_OK); + SetCloudSchemaForCollate(ageIsPrimaryKey); + + /** + * @tc.steps:step2. create distributed table with CLOUD_COOPERATION mode. + * @tc.expected: step2. return ok. + */ + EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName, DistributedDB::CLOUD_COOPERATION), OK); + + /** + * @tc.steps:step3. insert data in lower case. + * @tc.expected: step3. return ok. + */ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), E_OK); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); + + /** + * @tc.steps:step4. construct cloud data in upper case, call GetInfoByPrimaryKeyOrGid + * @tc.expected: step4. return expectCode. + */ + std::shared_ptr storageProxy = GetStorageProxy(g_cloudStore); + ASSERT_NE(storageProxy, nullptr); + EXPECT_EQ(storageProxy->StartTransaction(), E_OK); + VBucket vBucket; + std::string gid = g_gid + std::to_string(0); + vBucket["name"] = pkStr[0]; + if (ageIsPrimaryKey) { + vBucket["age"] = pkStr[1]; + } + vBucket[CloudDbConstant::GID_FIELD] = gid; + DataInfoWithLog dataInfoWithLog; + VBucket assetInfo; + EXPECT_EQ(storageProxy->GetInfoByPrimaryKeyOrGid(g_tableName, vBucket, dataInfoWithLog, assetInfo), expectCode); + EXPECT_EQ(storageProxy->Commit(), E_OK); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest014 + * @tc.desc: Test collate nocase for primary key(NOCASE followed by ','), case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest014, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE NOCASE, age text);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', '10');"; + std::vector pkStr = { "aBcD" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest015 + * @tc.desc: Test collate nocase for primary key, case match + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest015, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE NOCASE, age text);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', '10');"; + std::vector pkStr = { "abcd" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest016 + * @tc.desc: Test collate nocase for primary key(NOCASE followed by ')'), case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest016, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE NOCASE);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd');"; + std::vector pkStr = { "aBcD" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest017 + * @tc.desc: Test collate nocase for primary key(NOCASE followed by ' '), case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest017, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE NOCASE , age int);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', 10);"; + std::vector pkStr = { "aBcD" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest018 + * @tc.desc: Test collate nocase NOT for primary key, case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest018, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key, age TEXT COLLATE NOCASE);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', '10');"; + std::vector pkStr = { "aBcD" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false, -E_NOT_FOUND); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest019 + * @tc.desc: Test collate nocase for one primary key, one pk case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest019, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate NOCASE, age text," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', 'ab');"; + std::vector pkStr = { "aBcD", "ab" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest020 + * @tc.desc: Test collate nocase for one primary key, two pk case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest020, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate NOCASE, age text," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', 'aB');"; + std::vector pkStr = { "aBcD", "AB" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true, -E_NOT_FOUND); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest021 + * @tc.desc: Test collate nocase for two primary key, two pk case mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest021, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate NOCASE, age text collate nocase," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd', 'aB');"; + std::vector pkStr = { "aBcD", "ab" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest022 + * @tc.desc: Test collate rtrim for primary key(NOCASE followed by ','), trim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest022, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE RTRIM, age text);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ', '10');"; + std::vector pkStr = { "abcd" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest023 + * @tc.desc: Test collate nocase for primary key, trim match + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest023, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE RTRIM, age text);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd_', '10');"; + std::vector pkStr = { "abcd_" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest024 + * @tc.desc: Test collate rtrim for primary key(NOCASE followed by ')'), rtrim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest024, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key COLLATE rtrim);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ');"; + std::vector pkStr = { "abcd" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest025 + * @tc.desc: Test collate rtrim NOT for primary key, rtrim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest025, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(name text primary key, age TEXT COLLATE rtrim);"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ', '10');"; + std::vector pkStr = { "abcd" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, false, -E_NOT_FOUND); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest026 + * @tc.desc: Test collate rtrim for one primary key, one pk rtrim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest026, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate RTRIM, age text," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ', 'ab');"; + std::vector pkStr = { "abcd", "ab" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest026 + * @tc.desc: Test collate rtrim for one primary key, two pk rttim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest027, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate rtrim, age text," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ', 'aB ');"; + std::vector pkStr = { "abcd", "aB" }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true, -E_NOT_FOUND); + } + + /** + * @tc.name: GetInfoByPrimaryKeyOrGidTest027 + * @tc.desc: Test collate rtrim for two primary key, two pk rtrim mismatch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, GetInfoByPrimaryKeyOrGidTest028, TestSize.Level0) + { + std::string createSql = "create table " + g_tableName + "(NAME text collate rtrim, age text collate rtrim," + + "primary key(name, age));"; + std::string insertSql = "insert into " + g_tableName + " values('abcd ', 'ab');"; + std::vector pkStr = { "abcd ", "ab " }; + PrimaryKeyCollateTest(createSql, insertSql, pkStr, true); + } + void ConstructDownloadData(DownloadData &downloadData, GidType gidType, bool nullable, bool vBucketContains) { for (int i = 0; i < 7; i++) { // 7 is record counts @@ -1012,7 +1300,6 @@ namespace { EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); sql = "update " + DBCommon::GetLogTableName("t_cloud") + " set flag = 0"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); - return; /** * @tc.steps:step2. drop table t_cloud, check log data diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp index 025cc70c2624406972f86c1625389c249a8ab2e1..53089db134690ae237a4bf1035187d0b4bc59ca0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp @@ -40,6 +40,7 @@ namespace { constexpr auto FIELD_NAME_1 = "field_name_1"; constexpr auto FIELD_NAME_2 = "field_name_2"; constexpr auto FIELD_NAME_3 = "field_name_3"; + constexpr auto FIELD_NAME_4 = "FIELD_name_4"; std::unique_ptr g_schemaMgr = nullptr; @@ -210,6 +211,38 @@ DataBaseSchema g_schema2 = { } }; +DataBaseSchema g_schema3 = { + .tables = { + { + .name = TABLE_NAME_1, + .fields = { + { + .colName = FIELD_NAME_1, + .type = TYPE_INDEX, + .primary = true, + .nullable = true, + }, + { + .colName = FIELD_NAME_4, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + } + } + }, + { + .name = TABLE_NAME_2, + .fields = { + { + .colName = FIELD_NAME_4, + .type = TYPE_INDEX, + .primary = true, + .nullable = true, + } + } + } + } +}; FieldInfo SetField(std::string fieldName, std::string dataType, bool nullable) { @@ -586,4 +619,46 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest013, TestSize.Level0) localSchemaWithAssetPrimary.AddRelationalTable(table); EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_4, localSchemaWithAssetPrimary), -E_SCHEMA_MISMATCH); } + +/** + * @tc.name: SchemaMgrTest014 + * @tc.desc: test case insensitive when table 2 contain uppercase primary key, table 1 contain uppercase field. + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest014, TestSize.Level0) +{ + /** + * @tc.steps:step1. set local field1 uppercase and field4 lowercase + * @tc.expected: step1. return ok. + */ + FieldInfo field1 = SetField("FIELD_name_1", "int", true); + FieldInfo field4 = SetField("field_name_4", "int", true); + + TableInfo table1; + table1.SetTableName(TABLE_NAME_1); + table1.AddField(field1); + table1.AddField(field4); + table1.SetPrimaryKey(FIELD_NAME_1, 1); + table1.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); + + TableInfo table2; + table2.SetTableName(TABLE_NAME_2); + table2.AddField(field4); + table2.SetPrimaryKey(FIELD_NAME_4, 1); + table2.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); + + RelationalSchemaObject localSchema; + localSchema.AddRelationalTable(table1); + localSchema.AddRelationalTable(table2); + + /** + * @tc.steps:step2. cloud schema's field1 is lowercase, field4 is uppercase + * @tc.expected: step2. return ok. + */ + g_schemaMgr->SetCloudDbSchema(g_schema3); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_1, localSchema), E_OK); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_2, localSchema), E_OK); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp index cfd5ae1cc2f45c54f3e1e5549faea7b2bd6f7010..e494e9c2776ffc1f675f1b2e6ffcc15d68efc2ef 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp @@ -15,17 +15,19 @@ #ifdef RELATIONAL_STORE #include +#include "cloud_db_constant.h" +#include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_unit_test.h" +#include "log_table_manager_factory.h" +#include "query_sync_object.h" +#include "relational_store_instance.h" #include "relational_store_manager.h" -#include "distributeddb_data_generate_unit_test.h" #include "relational_sync_able_storage.h" -#include "relational_store_instance.h" -#include "sqlite_relational_store.h" -#include "log_table_manager_factory.h" -#include "cloud_db_constant.h" #include "runtime_config.h" +#include "sqlite_relational_store.h" #include "virtual_cloud_data_translate.h" + using namespace testing::ext; using namespace DistributedDB; using namespace DistributedDBUnitTest; @@ -550,12 +552,15 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount001, Tes * @tc.expected: return -SQLITE_ERROR. */ int64_t resCount = 0; - EXPECT_EQ(g_cloudStore->GetUploadCount(g_tableName, g_startTime, false, resCount), -SQLITE_ERROR); + QuerySyncObject query; + query.SetTableName(g_tableName); + EXPECT_EQ(g_cloudStore->GetUploadCount(query, g_startTime, false, resCount), -E_INVALID_QUERY_FORMAT); CreateLogTable(); int64_t insCount = 100; + CreateAndInitUserTable(insCount, insCount); InitLogData(insCount, insCount, insCount, insCount); - EXPECT_EQ(g_cloudStore->GetUploadCount(g_tableName, g_startTime, false, resCount), E_OK); + EXPECT_EQ(g_cloudStore->GetUploadCount(query, g_startTime, false, resCount), E_OK); EXPECT_EQ(resCount, insCount + insCount + insCount); /** @@ -563,7 +568,7 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount001, Tes * @tc.expected: count is 0 and return E_OK. */ Timestamp invalidTime = g_startTime + g_startTime; - EXPECT_EQ(g_cloudStore->GetUploadCount(g_tableName, invalidTime, false, resCount), E_OK); + EXPECT_EQ(g_cloudStore->GetUploadCount(query, invalidTime, false, resCount), E_OK); EXPECT_EQ(resCount, 0); } @@ -579,6 +584,7 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount002, Tes CreateLogTable(); int64_t insCount = 100; InitLogData(insCount, insCount, 0, insCount); + CreateAndInitUserTable(insCount, insCount); int64_t resCount = 0; /** @@ -614,6 +620,7 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount003, Tes { CreateLogTable(); int64_t insCount = 100; + CreateAndInitUserTable(insCount, insCount); InitLogData(0, 0, insCount, insCount); int64_t resCount = 0; @@ -828,7 +835,9 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetCloudData001, TestS * @tc.expected: return -E_INVALID_DB. */ int timeOffset = 10; - EXPECT_EQ(g_cloudStore->GetCloudData(g_tableSchema, g_startTime + timeOffset, token, cloudSyncData), -E_INVALID_DB); + QuerySyncObject object; + EXPECT_EQ(g_cloudStore->GetCloudData(g_tableSchema, object, g_startTime + timeOffset, token, cloudSyncData), + -E_INVALID_DB); EXPECT_EQ(g_storageProxy->StartTransaction(), E_OK); EXPECT_EQ(g_storageProxy->GetCloudData(g_tableName, g_startTime + timeOffset, token, cloudSyncData), E_OK); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..786d56e60303ab9804f3ea40d5f73fcccf43032f --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.cpp @@ -0,0 +1,298 @@ +/* + * 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 "cloud_db_sync_utils_test.h" + +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace DistributedDB { + string g_storeID = "Relational_Store_SYNC"; + const string TABLE_NAME = "worker"; + const string DEVICE_CLOUD = "cloud_dev"; + const int64_t SYNC_WAIT_TIME = 60; + int g_syncIndex = 0; + string g_storePath = ""; + std::mutex g_processMutex; + std::condition_variable g_processCondition; + DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID); + SyncProcess g_syncProcess; + using CloudSyncStatusCallback = std::function &onProcess)>; + const std::vector g_tables = {TABLE_NAME}; + const Asset g_cloudAsset1 = { + .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync", + .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC" + }; + const Asset g_cloudAsset2 = { + .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync", + .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "UPDATE" + }; + + void CloudDBSyncUtilsTest::SetStorePath(const std::string &path) + { + g_storePath = path; + } + + void CloudDBSyncUtilsTest::InitSyncUtils(std::vector cloudField, RelationalStoreObserverUnitTest *&observer, + std::shared_ptr &virtualCloudDb, std::shared_ptr &virtualAssetLoader, + RelationalStoreDelegate *&delegate) + { + observer = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(observer, nullptr); + ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option { .observer = observer }, + delegate), DBStatus::OK); + ASSERT_NE(delegate, nullptr); + ASSERT_EQ(delegate->CreateDistributedTable(TABLE_NAME, CLOUD_COOPERATION), DBStatus::OK); + virtualCloudDb = make_shared(); + virtualAssetLoader = make_shared(); + g_syncProcess = {}; + ASSERT_EQ(delegate->SetCloudDB(virtualCloudDb), DBStatus::OK); + ASSERT_EQ(delegate->SetIAssetLoader(virtualAssetLoader), DBStatus::OK); + // sync before setting cloud db schema,it should return SCHEMA_MISMATCH + Query query = Query::Select().FromTable(g_tables); + CloudSyncStatusCallback callback; + ASSERT_EQ(delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, SYNC_WAIT_TIME), + DBStatus::SCHEMA_MISMATCH); + DataBaseSchema dataBaseSchema; + GetCloudDbSchema(TABLE_NAME, cloudField, dataBaseSchema); + ASSERT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK); + } + + void CloudDBSyncUtilsTest::CreateUserDBAndTable(sqlite3 *&db, std::string sql) + { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); + } + + void CloudDBSyncUtilsTest::InsertCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull, + std::shared_ptr &virtualCloudDb) + { + std::vector photo(photoSize, 'v'); + std::vector record; + std::vector extend; + Timestamp now = TimeHelper::GetSysCurrentTime(); + for (int64_t i = begin; i < begin + count; ++i) { + VBucket data; + data.insert_or_assign("name", "Cloud" + std::to_string(i)); + data.insert_or_assign("height", 166.0); // 166.0 is random double value + data.insert_or_assign("married", false); + data.insert_or_assign("photo", photo); + data.insert_or_assign("age", 13L); // 13 is random int64_t value + Asset asset = g_cloudAsset1; + asset.name = asset.name + std::to_string(i); + assetIsNull ? data.insert_or_assign("asset", Nil()) : data.insert_or_assign("asset", asset); + record.push_back(data); + VBucket log; + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, + static_cast(now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, + static_cast(now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + extend.push_back(log); + } + ASSERT_EQ(virtualCloudDb->BatchInsert(TABLE_NAME, std::move(record), extend), DBStatus::OK); + LOGD("insert cloud record worker[primary key]:[cloud%" PRId64 " - cloud%" PRId64")", begin, count); + std::this_thread::sleep_for(std::chrono::milliseconds(count)); + } + + void CloudDBSyncUtilsTest::UpdateCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull, + std::shared_ptr &virtualCloudDb) + { + std::vector photo(photoSize, 'v'); + std::vector record; + std::vector extend; + Timestamp now = TimeHelper::GetSysCurrentTime(); + for (int64_t i = begin; i < begin + count; ++i) { + VBucket data; + data.insert_or_assign("name", "Cloud" + std::to_string(i)); + data.insert_or_assign("height", 188.0); // 188.0 is random double value + data.insert_or_assign("married", false); + data.insert_or_assign("photo", photo); + data.insert_or_assign("age", 13L); // 13 is random int64_t value + Asset asset = g_cloudAsset2; + asset.name = asset.name + std::to_string(i); + assetIsNull ? data.insert_or_assign("asset", Nil()) : data.insert_or_assign("asset", asset); + record.push_back(data); + VBucket log; + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, + static_cast(now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, + static_cast(now / CloudDbConstant::TEN_THOUSAND + i)); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign(CloudDbConstant::GID_FIELD, to_string(i)); + extend.push_back(log); + } + ASSERT_EQ(virtualCloudDb->BatchUpdate(TABLE_NAME, std::move(record), extend), DBStatus::OK); + LOGD("update cloud record worker[primary key]:[cloud%" PRId64 " - cloud%" PRId64")", begin, count); + std::this_thread::sleep_for(std::chrono::milliseconds(count)); + } + + void CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(int64_t begin, int64_t count, + std::shared_ptr &virtualCloudDb) + { + for (int64_t i = begin; i < begin + count; ++i) { + VBucket data; + data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i)); + ASSERT_EQ(virtualCloudDb->DeleteByGid(TABLE_NAME, data), DBStatus::OK); + } + LOGD("delete cloud record worker[primary key]:[cloud%" PRId64 " - cloud%" PRId64")", begin, count); + std::this_thread::sleep_for(std::chrono::milliseconds(count)); + } + + void CloudDBSyncUtilsTest::GetCallback(SyncProcess &syncProcess, CloudSyncStatusCallback &callback, + std::vector &expectProcess) + { + g_syncIndex = 0; + callback = [&syncProcess, &expectProcess](const std::map &process) { + LOGI("devices size = %d", process.size()); + ASSERT_EQ(process.size(), 1u); + syncProcess = std::move(process.begin()->second); + ASSERT_EQ(process.begin()->first, DEVICE_CLOUD); + ASSERT_NE(syncProcess.tableProcess.empty(), true); + LOGI("current sync process status:%d, db status:%d ", syncProcess.process, syncProcess.errCode); + std::for_each(g_tables.begin(), g_tables.end(), [&](const auto &item) { + auto table1 = syncProcess.tableProcess.find(item); + if (table1 != syncProcess.tableProcess.end()) { + LOGI("table[%s], table process status:%d, [downloadInfo](batchIndex:%u, total:%u, successCount:%u, " + "failCount:%u) [uploadInfo](batchIndex:%u, total:%u, successCount:%u,failCount:%u", + item.c_str(), table1->second.process, table1->second.downLoadInfo.batchIndex, + table1->second.downLoadInfo.total, table1->second.downLoadInfo.successCount, + table1->second.downLoadInfo.failCount, table1->second.upLoadInfo.batchIndex, + table1->second.upLoadInfo.total, table1->second.upLoadInfo.successCount, + table1->second.upLoadInfo.failCount); + } + }); + if (expectProcess.empty()) { + if (syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + return; + } + ASSERT_LE(static_cast(g_syncIndex), expectProcess.size()); + for (size_t i = 0; i < g_tables.size(); ++i) { + SyncProcess head = expectProcess[g_syncIndex]; + for (auto &expect : head.tableProcess) { + auto real = syncProcess.tableProcess.find(expect.first); + ASSERT_NE(real, syncProcess.tableProcess.end()); + EXPECT_EQ(expect.second.process, real->second.process); + EXPECT_EQ(expect.second.downLoadInfo.batchIndex, real->second.downLoadInfo.batchIndex); + EXPECT_EQ(expect.second.downLoadInfo.total, real->second.downLoadInfo.total); + EXPECT_EQ(expect.second.downLoadInfo.successCount, real->second.downLoadInfo.successCount); + EXPECT_EQ(expect.second.downLoadInfo.failCount, real->second.downLoadInfo.failCount); + EXPECT_EQ(expect.second.upLoadInfo.batchIndex, real->second.upLoadInfo.batchIndex); + EXPECT_EQ(expect.second.upLoadInfo.total, real->second.upLoadInfo.total); + EXPECT_EQ(expect.second.upLoadInfo.successCount, real->second.upLoadInfo.successCount); + EXPECT_EQ(expect.second.upLoadInfo.failCount, real->second.upLoadInfo.failCount); + } + } + g_syncIndex++; + if (syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + } + + void CloudDBSyncUtilsTest::CheckCloudTotalCount(std::vector expectCounts, + const std::shared_ptr &virtualCloudDb) + { + VBucket extend; + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); + for (size_t i = 0; i < g_tables.size(); ++i) { + int64_t realCount = 0; + std::vector data; + virtualCloudDb->Query(g_tables[i], extend, data); + for (size_t j = 0; j < data.size(); ++j) { + auto entry = data[j].find(CloudDbConstant::DELETE_FIELD); + if (entry != data[j].end() && std::get(entry->second)) { + continue; + } + realCount++; + } + EXPECT_EQ(realCount, expectCounts[i]); // ExpectCount represents the total amount of cloud data. + } + } + + void CloudDBSyncUtilsTest::WaitForSyncFinish(SyncProcess &syncProcess, const int64_t &waitTime) + { + std::unique_lock lock(g_processMutex); + bool result = g_processCondition.wait_for(lock, std::chrono::seconds(waitTime), [&syncProcess]() { + return syncProcess.process == FINISHED; + }); + ASSERT_EQ(result, true); + LOGD("-------------------sync end--------------"); + } + + void CloudDBSyncUtilsTest::callSync(const std::vector &tableNames, SyncMode mode, DBStatus dbStatus, + RelationalStoreDelegate *&delegate) + { + g_syncProcess = {}; + Query query = Query::Select().FromTable(tableNames); + std::vector expectProcess; + CloudSyncStatusCallback callback; + GetCallback(g_syncProcess, callback, expectProcess); + ASSERT_EQ(delegate->Sync({DEVICE_CLOUD}, mode, query, callback, SYNC_WAIT_TIME), dbStatus); + if (dbStatus == DBStatus::OK) { + WaitForSyncFinish(g_syncProcess, SYNC_WAIT_TIME); + } + } + + void CloudDBSyncUtilsTest::CloseDb(RelationalStoreObserverUnitTest *&observer, + std::shared_ptr &virtualCloudDb, RelationalStoreDelegate *&delegate) + { + delete observer; + virtualCloudDb = nullptr; + if (delegate != nullptr) { + EXPECT_EQ(g_mgr.CloseStore(delegate), DBStatus::OK); + delegate = nullptr; + } + } + + int CloudDBSyncUtilsTest::QueryCountCallback(void *data, int count, char **colValue, char **colName) + { + if (count != 1) { + return 0; + } + auto expectCount = reinterpret_cast(data); + EXPECT_EQ(strtol(colValue[0], nullptr, 10), expectCount); // 10: decimal + return 0; + } + + void CloudDBSyncUtilsTest::CheckDownloadResult(sqlite3 *&db, std::vector expectCounts, std::string keyStr) + { + for (size_t i = 0; i < g_tables.size(); ++i) { + string queryDownload = "select count(*) from " + g_tables[i] + " where name " + + " like '" + keyStr + "%'"; + EXPECT_EQ(sqlite3_exec(db, queryDownload.c_str(), QueryCountCallback, + reinterpret_cast(expectCounts[i]), nullptr), SQLITE_OK); + } + } + + void CloudDBSyncUtilsTest::CheckLocalRecordNum(sqlite3 *&db, std::string tableName, int count) + { + std::string sql = "select count(*) from " + tableName + ";"; + EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback, + reinterpret_cast(count), nullptr), SQLITE_OK); + } + + void CloudDBSyncUtilsTest::GetCloudDbSchema(std::string tableName, std::vector cloudField, + DataBaseSchema &dataBaseSchema) + { + TableSchema tableSchema = { + .name = tableName, + .fields = cloudField + }; + dataBaseSchema.tables.push_back(tableSchema); + } +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.h new file mode 100644 index 0000000000000000000000000000000000000000..57026676aa6adbc7bf9e6f89ff33c36bfcd72a04 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_db_sync_utils_test.h @@ -0,0 +1,85 @@ +/* + * 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 CLOUD_DB_SYNC_UTILS_TEST_H +#define CLOUD_DB_SYNC_UTILS_TEST_H + +#include +#include +#include "cloud/cloud_storage_utils.h" +#include "cloud_db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "process_system_api_adapter_impl.h" +#include "relational_store_instance.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "sqlite_relational_store.h" +#include "sqlite_relational_utils.h" +#include "store_observer.h" +#include "time_helper.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" +#include "virtual_cloud_db.h" + +namespace DistributedDB { + using namespace DistributedDBUnitTest; + using CloudSyncStatusCallback = std::function &onProcess)>; + +class CloudDBSyncUtilsTest { +public: + static void SetStorePath(const std::string &path); + + static void InitSyncUtils(std::vector cloudField, RelationalStoreObserverUnitTest *&observer, + std::shared_ptr &virtualCloudDb, std::shared_ptr &virtualAssetLoader, + RelationalStoreDelegate *&delegate); + + static void CreateUserDBAndTable(sqlite3 *&db, std::string sql); + + static void InsertCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull, + std::shared_ptr &virtualCloudDb); + + static void UpdateCloudTableRecord(int64_t begin, int64_t count, int64_t photoSize, bool assetIsNull, + std::shared_ptr &virtualCloudDb); + + static void DeleteCloudTableRecordByGid(int64_t begin, int64_t count, + std::shared_ptr &virtualCloudDb); + + static void GetCallback(SyncProcess &syncProcess, CloudSyncStatusCallback &callback, + std::vector &expectProcess); + + static void CheckCloudTotalCount(std::vector expectCounts, + const std::shared_ptr &virtualCloudDb); + + static void WaitForSyncFinish(SyncProcess &syncProcess, const int64_t &waitTime); + + static void callSync(const std::vector &tableNames, SyncMode mode, DBStatus dbStatus, + RelationalStoreDelegate *&delegate); + + static void CloseDb(RelationalStoreObserverUnitTest *&observer, + std::shared_ptr &virtualCloudDb, RelationalStoreDelegate *&delegate); + + static int QueryCountCallback(void *data, int count, char **colValue, char **colName); + + static void CheckDownloadResult(sqlite3 *&db, std::vector expectCounts, std::string keyStr); + + static void CheckLocalRecordNum(sqlite3 *&db, std::string tableName, int count); + + static void GetCloudDbSchema(std::string tableName, std::vector cloudField, + DataBaseSchema &dataBaseSchema); +}; +} + +#endif // CLOUD_DB_SYNC_UTILS_TEST_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h index ae5f38d386927d7495c4b8e9c65a16def34f7933..c0d4b88ede2ad4e62a9b81fc29ac7bbfa74affe7 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h @@ -18,6 +18,7 @@ #include "cloud_merge_strategy.h" #include "cloud_syncer.h" #include "cloud_syncer_test.h" +#include "cloud_sync_utils.h" #include "mock_iclouddb.h" namespace DistributedDB { @@ -94,13 +95,13 @@ public: void InitCloudSyncerForSync() { this->closed_ = false; - this->cloudTaskInfos_[this->currentTaskId_].callback = [this]( + this->cloudTaskInfos_[this->lastTaskId_].callback = [this]( const std::map &process) { if (process.size() == 1u) { - process_[this->currentTaskId_] = process.begin()->second; + process_[this->lastTaskId_] = process.begin()->second; } else { SyncProcess tmpProcess; - process_[this->currentTaskId_] = tmpProcess; + process_[this->lastTaskId_] = tmpProcess; } }; } @@ -145,7 +146,7 @@ public: void CallClearCloudSyncData(CloudSyncData& uploadData) { - this->ClearCloudSyncData(uploadData); + CloudSyncUtils::ClearCloudSyncData(uploadData); } int32_t GetUploadSuccessCount(TaskId taskId) @@ -167,11 +168,6 @@ public: { this->cloudDB_.SetCloudDB(icloudDB); } - - void CallDoFinished(TaskId taskId, int errCode, const InnerProcessInfo &processInfo) - { - DoFinished(taskId, errCode, processInfo); - } CloudTaskInfo SetAndGetCloudTaskInfo(SyncMode mode, std::vector table, SyncProcessCallback callback, int64_t timeout) diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp index 7213c386916b5b5c9ffe30d3aa01b16144dd47f8..e8febffcd35a521d747e7770b0ed549b422ba3b9 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp @@ -211,6 +211,7 @@ namespace { void DistributedDBCloudAssetCompareTest::TearDown(void) { + RefObject::DecObjRef(g_store); if (g_delegate != nullptr) { EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK); g_delegate = nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp index 231b3264bbb3fc3a4985186707084d6aa6c6e053..220b67867e2630e69e289729e3fcbc0eef681667 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp @@ -659,6 +659,7 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudSyncQueue001, TestSize.Level2) EXPECT_EQ(Sync(cloudSyncer, callCount), OK); RuntimeContext::GetInstance()->StopTaskPool(); EXPECT_EQ(callCount, 1); + RefObject::KillAndDecObjRef(cloudSyncer); } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afdf9a7adaa3de11ebbcfdd20b484e2e9d5fce10 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp @@ -0,0 +1,314 @@ +/* + * 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. + */ +#ifdef RELATIONAL_STORE +#include "cloud/cloud_storage_utils.h" +#include "cloud_db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "mock_asset_loader.h" +#include "process_system_api_adapter_impl.h" +#include "relational_store_instance.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "sqlite_relational_store.h" +#include "sqlite_relational_utils.h" +#include "time_helper.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" +#include "virtual_cloud_db.h" +#include +#include + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { +const string STORE_ID = "Relational_Store_SYNC"; +const string DB_SUFFIX = ".db"; +const string ASSETS_TABLE_NAME = "student"; +const string DEVICE_CLOUD = "cloud_dev"; +const string COL_ID = "id"; +const string COL_NAME = "name"; +const string COL_HEIGHT = "height"; +const string COL_ASSETS = "assets"; +const string COL_AGE = "age"; +const int64_t SYNC_WAIT_TIME = 600; +const std::vector CLOUD_FIELDS = {{COL_ID, TYPE_INDEX, true}, {COL_NAME, TYPE_INDEX}, + {COL_HEIGHT, TYPE_INDEX}, {COL_ASSETS, TYPE_INDEX}, {COL_AGE, TYPE_INDEX}}; +const string CREATE_SINGLE_PRIMARY_KEY_TABLE = "CREATE TABLE IF NOT EXISTS " + ASSETS_TABLE_NAME + "(" + COL_ID + + " INTEGER PRIMARY KEY," + COL_NAME + " TEXT ," + COL_HEIGHT + " REAL ," + + COL_ASSETS + " BLOB," + COL_AGE + " INT);"; +const string INSERT_SQL = "insert or replace into " + ASSETS_TABLE_NAME + " values (?,?,?,?,?);"; +const Asset ASSET_COPY = {.version = 1, + .name = "Phone", + .assetId = "0", + .subpath = "/local/sync", + .uri = "/local/sync", + .modifyTime = "123456", + .createTime = "", + .size = "256", + .hash = "ASE"}; + +string g_storePath; +string g_testDir; +RelationalStoreObserverUnitTest *g_observer = nullptr; +DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID); +RelationalStoreDelegate *g_delegate = nullptr; +std::shared_ptr g_virtualCloudDb; +std::shared_ptr g_virtualAssetLoader; +SyncProcess g_syncProcess; +std::condition_variable g_processCondition; +std::mutex g_processMutex; +using CloudSyncStatusCallback = std::function &onProcess)>; + +void InitDatabase(sqlite3 *&db) +{ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_SINGLE_PRIMARY_KEY_TABLE), SQLITE_OK); +} + +void GetCloudDbSchema(DataBaseSchema &dataBaseSchema) +{ + TableSchema assetsTableSchema = {.name = ASSETS_TABLE_NAME, .fields = CLOUD_FIELDS}; + dataBaseSchema.tables.push_back(assetsTableSchema); +} + +void GenerateDataRecords( + int64_t begin, int64_t count, int64_t gidStart, std::vector &record, std::vector &extend) +{ + for (int64_t i = begin; i < begin + count; i++) { + Assets assets; + Asset asset = ASSET_COPY; + asset.name = ASSET_COPY.name + std::to_string(i); + assets.emplace_back(asset); + VBucket data; + data.insert_or_assign(COL_ID, i); + data.insert_or_assign(COL_NAME, "name" + std::to_string(i)); + data.insert_or_assign(COL_HEIGHT, 166.0 * i); // 166.0 is random double value + data.insert_or_assign(COL_ASSETS, assets); + data.insert_or_assign(COL_AGE, 18L + i); // 18 is random int value + record.push_back(data); + + VBucket log; + Timestamp now = TimeHelper::GetSysCurrentTime(); + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i + gidStart)); + extend.push_back(log); + } +} + +void InsertLocalData(sqlite3 *&db, int64_t begin, int64_t count) +{ + int errCode; + std::vector record; + std::vector extend; + std::vector assetBlob; + GenerateDataRecords(begin, count, 0, record, extend); + for (VBucket vBucket : record) { + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, INSERT_SQL, stmt), E_OK); + ASSERT_EQ(SQLiteUtils::BindInt64ToStatement(stmt, 1, std::get(vBucket[COL_ID])), E_OK); // 1 is id + ASSERT_EQ(SQLiteUtils::BindTextToStatement(stmt, 2, std::get(vBucket[COL_NAME])), E_OK); // 2 is name + ASSERT_EQ(SQLiteUtils::MapSQLiteErrno( + sqlite3_bind_double(stmt, 3, std::get(vBucket[COL_HEIGHT]))), E_OK); // 3 is height + RuntimeContext::GetInstance()->AssetsToBlob(std::get(vBucket[COL_ASSETS]), assetBlob); + ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 4, assetBlob, false), E_OK); // 4 is assets + ASSERT_EQ(SQLiteUtils::BindInt64ToStatement(stmt, 5, std::get(vBucket[COL_AGE])), E_OK); // 5 is age + EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + SQLiteUtils::ResetStatement(stmt, true, errCode); + } + LOGD("insert into student table [primary key]:[%" PRId64 " - %" PRId64 ")", begin, begin + count); +} + +void DeleteCloudDBData(int64_t begin, int64_t count) +{ + for (int64_t i = begin; i < begin + count; i++) { + VBucket idMap; + idMap.insert_or_assign("#_gid", std::to_string(i)); + ASSERT_EQ(g_virtualCloudDb->DeleteByGid(ASSETS_TABLE_NAME, idMap), DBStatus::OK); + } +} + +void InsertCloudDBData(int64_t begin, int64_t count, int64_t gidStart) +{ + std::vector record; + std::vector extend; + GenerateDataRecords(begin, count, gidStart, record, extend); + ASSERT_EQ(g_virtualCloudDb->BatchInsertWithGid(ASSETS_TABLE_NAME, std::move(record), extend), DBStatus::OK); +} + +void WaitForSyncFinish(SyncProcess &syncProcess, const int64_t &waitTime) +{ + std::unique_lock lock(g_processMutex); + bool result = g_processCondition.wait_for( + lock, std::chrono::seconds(waitTime), [&syncProcess]() { return syncProcess.process == FINISHED; }); + ASSERT_EQ(result, true); + LOGD("-------------------sync end--------------"); +} + +void CallSync(const std::vector &tableNames, SyncMode mode, DBStatus dbStatus) +{ + g_syncProcess = {}; + Query query = Query::Select().FromTable(tableNames); + std::vector expectProcess; + CloudSyncStatusCallback callback = [](const std::map &process) { + ASSERT_EQ(process.begin()->first, DEVICE_CLOUD); + g_syncProcess = std::move(process.begin()->second); + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, mode, query, callback, SYNC_WAIT_TIME), dbStatus); + + if (dbStatus == DBStatus::OK) { + WaitForSyncFinish(g_syncProcess, SYNC_WAIT_TIME); + } +} + +void CheckDownloadForTest001(int index, map &assets) +{ + for (auto &item : assets) { + for (auto &asset : item.second) { + EXPECT_EQ(asset.status, static_cast(AssetStatus::DOWNLOADING)); + if (index > 2) { // 1, 2 is deleted; 3, 4 is inserted + EXPECT_EQ(asset.flag, static_cast(AssetOpType::INSERT)); + } else { + EXPECT_EQ(asset.flag, static_cast(AssetOpType::DELETE)); + } + LOGD("asset [name]:%s, [status]:%u, [flag]:%u, [index]:%d", asset.name.c_str(), asset.status, asset.flag, + index); + } + } +} + +void CloseDb() +{ + delete g_observer; + g_virtualCloudDb = nullptr; + if (g_delegate != nullptr) { + EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK); + g_delegate = nullptr; + } +} + +class DistributedDBCloudSyncerDownloadAssetsTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + protected: + sqlite3 *db = nullptr; +}; + +void DistributedDBCloudSyncerDownloadAssetsTest::SetUpTestCase(void) +{ + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + g_storePath = g_testDir + "/" + STORE_ID + DB_SUFFIX; + LOGI("The test db is:%s", g_storePath.c_str()); + RuntimeConfig::SetCloudTranslate(std::make_shared()); +} + +void DistributedDBCloudSyncerDownloadAssetsTest::TearDownTestCase(void) {} + +void DistributedDBCloudSyncerDownloadAssetsTest::SetUp(void) +{ + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + LOGD("Test dir is %s", g_testDir.c_str()); + db = RelationalTestUtils::CreateDataBase(g_storePath); + ASSERT_NE(db, nullptr); + InitDatabase(db); + g_observer = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(g_observer, nullptr); + ASSERT_EQ( + g_mgr.OpenStore(g_storePath, STORE_ID, RelationalStoreDelegate::Option{.observer = g_observer}, g_delegate), + DBStatus::OK); + ASSERT_NE(g_delegate, nullptr); + ASSERT_EQ(g_delegate->CreateDistributedTable(ASSETS_TABLE_NAME, CLOUD_COOPERATION), DBStatus::OK); + g_virtualCloudDb = make_shared(); + g_virtualAssetLoader = make_shared(); + g_syncProcess = {}; + ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK); + ASSERT_EQ(g_delegate->SetIAssetLoader(g_virtualAssetLoader), DBStatus::OK); + DataBaseSchema dataBaseSchema; + GetCloudDbSchema(dataBaseSchema); + ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK); +} + +void DistributedDBCloudSyncerDownloadAssetsTest::TearDown(void) +{ + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } +} + +/** + * @tc.name: DownloadAssetForDupDataTest001 + * @tc.desc: Test the download interface call with duplicate data for the same primary key. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liufuchenxing + */ +HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, DownloadAssetForDupDataTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Mock asset download interface. + * @tc.expected: step1. return OK and interface will be called 4 times. delete 1, delete 2, insert 1, insert 2 + */ + std::shared_ptr assetLoader = make_shared(); + ASSERT_EQ(g_delegate->SetIAssetLoader(assetLoader), DBStatus::OK); + int index = 1; + EXPECT_CALL(*assetLoader, Download(testing::_, testing::_, testing::_, testing::_)) + .Times(4) + .WillRepeatedly( + [&index](const std::string &, const std::string &gid, const Type &, std::map &assets) { + LOGD("Download GID:%s", gid.c_str()); + CheckDownloadForTest001(index, assets); + index++; + return DBStatus::OK; + }); + + /** + * @tc.steps:step2. Insert local data [0, 10), sync data + * @tc.expected: step2. sync success. + */ + InsertLocalData(db, 0, 10); + CallSync({ASSETS_TABLE_NAME}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step3. delete cloud data [1, 2], then insert cloud data [1,2] with new gid. Finally sync data. + * @tc.expected: step3. sync success. + */ + DeleteCloudDBData(1, 2); + InsertCloudDBData(1, 2, 10); + CallSync({ASSETS_TABLE_NAME}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step4. close db. + * @tc.expected: step4. close success. + */ + CloseDb(); +} +} // namespace +#endif // RELATIONAL_STORE diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp index 764784bd38ef30686cd625743d3f5720ba2f55a2..70891e4bebb162833f914b051741e81b81fb6dc7 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp @@ -39,19 +39,21 @@ public: MockICloudSyncStorageInterface *g_iCloud = nullptr; std::shared_ptr g_storageProxy = nullptr; MockICloudDB *g_idb = nullptr; -std::unique_ptr g_cloudSyncer = nullptr; +TestCloudSyncer *g_cloudSyncer = nullptr; void DistributedDBCloudSyncerDownloadTest::SetUpTestCase(void) { g_iCloud = new MockICloudSyncStorageInterface(); g_storageProxy = std::make_shared(g_iCloud); - g_cloudSyncer = std::make_unique(g_storageProxy); + g_cloudSyncer = new(std::nothrow) TestCloudSyncer(g_storageProxy); + ASSERT_NE(g_cloudSyncer, nullptr); g_idb = new MockICloudDB(); g_cloudSyncer->SetMockICloudDB(g_idb); } void DistributedDBCloudSyncerDownloadTest::TearDownTestCase(void) { + RefObject::KillAndDecObjRef(g_cloudSyncer); g_cloudSyncer = nullptr; g_storageProxy = nullptr; delete g_iCloud; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp index 7af31ffc65203e51a60d57b59e59ed38b420b1a6..377b906ef92c96843c2ad86d400cac6cb9719111 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp @@ -68,7 +68,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck001, TestSiz cloudSyncer.SetMockICloudDB(idb); std::vector devices = {"cloud"}; std::vector tables = {"TestTableA", "TestTableB" }; - + // check different sync mode cloudSyncer.InitCloudSyncerForSync(); @@ -84,7 +84,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck001, TestSiz EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK)); SyncProcess res; int errCode = cloudSyncer.Sync(devices, SYNC_MODE_CLOUD_FORCE_PUSH, tables, [&res]( @@ -126,7 +126,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck002, TestSiz TestCloudSyncer cloudSyncer3(storageProxy); cloudSyncer3.SetMockICloudDB(idb); cloudSyncer3.InitCloudSyncerForSync(); - + std::vector devices = {"cloud"}; std::vector tables = {"TestTableA", "TestTableB" }; EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END)); @@ -141,7 +141,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck002, TestSiz EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK)); SyncProcess res; int errCode = cloudSyncer3.Sync(devices, SYNC_MODE_CLOUD_MERGE, tables, [&res]( @@ -184,7 +184,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck003, TestSiz std::shared_ptr idb = std::make_shared(); cloudSyncer5.SetMockICloudDB(idb); cloudSyncer5.InitCloudSyncerForSync(); - + std::vector tables = {"TestTableA", "TestTableB" }; EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END)); EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK)); @@ -198,7 +198,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck003, TestSiz EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK)); SyncProcess res; // check if device is empty @@ -244,7 +244,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck004, TestSiz cloudSyncer.taskInfo_ = cloudSyncer.SetAndGetCloudTaskInfo(SYNC_MODE_CLOUD_FORCE_PUSH, tables, onProcess, 5000); int errCode = cloudSyncer.CallTryToAddSyncTask(std::move(cloudSyncer.taskInfo_)); EXPECT_EQ(errCode, -E_BUSY); - + cloudSyncer.PopTaskQueue(); cloudSyncer.PopTaskQueue(); @@ -277,7 +277,7 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck005, TestSiz std::vector devices = {"cloud"}; std::vector tables = {"TestTableA", "TestTableB" }; - + cloudSyncer.InitCloudSyncer(0u, SYNC_MODE_CLOUD_FORCE_PUSH); int errCode = cloudSyncer.CreateCloudTaskInfoAndCallTryToAddSync(SYNC_MODE_CLOUD_FORCE_PUSH, tables, {}, 5000); errCode = cloudSyncer.CallPrepareSync(1u); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp index 0170c760251b2082277e40c5fd57acb276078970..77eb89f0a928e12a1329acb84f989254a9c2a75f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp @@ -98,7 +98,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck001, TestSize.Level1 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, Rollback()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillRepeatedly(Return(E_OK)); cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_PUSH_ONLY); int errCode = cloudSyncer->CallDoUpload(taskId); @@ -155,7 +155,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck002, TestSize.Level1 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, Rollback()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillRepeatedly(Return(E_OK)); // 1. The water level was read successfully cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE); @@ -191,7 +191,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck003, TestSize.Level1 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, Rollback()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK)); // 2. Failed to read water level @@ -265,7 +265,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck005, TestSize.Level1 EXPECT_CALL(*iCloud, Rollback()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillRepeatedly(Return(E_OK)); // 2. get total upload count ok cloudSyncer->InitCloudSyncer(10u, SYNC_MODE_CLOUD_FORCE_PUSH); @@ -276,7 +276,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck005, TestSize.Level1 // 3. get total upload count ok, which is 0 cloudSyncer->InitCloudSyncer(11u, SYNC_MODE_CLOUD_FORCE_PUSH); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillOnce([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillOnce([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 0; return E_OK; }); @@ -319,7 +319,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck006, TestSize.Level1 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, ReleaseCloudDataToken(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 1000; return E_OK; }); @@ -332,8 +332,9 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck006, TestSize.Level1 // batch_1 CloudSyncData quantity > total count uploadData.insData.record = std::vector(1001, tmp); uploadData.insData.extend = std::vector(1001, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillOnce( - [&uploadData](const TableSchema &, const Timestamp &, ContinueToken &, CloudSyncData &cloudDataResult) { + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillOnce( + [&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &, + CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; }); @@ -368,7 +369,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck007, TestSize.Level1 BatchExpectCall(iCloud); EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 1000; return E_OK; }); @@ -380,19 +381,19 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck007, TestSize.Level1 pair(CloudDbConstant::CREATE_FIELD, 1) }; uploadData2.insData.record = std::vector(1000, tmp); uploadData2.insData.extend = std::vector(1000, tmp); - + SyncTimeRange syncTimeRange = { .beginTime = 1u }; QueryObject queryObject(Query::Select()); queryObject.SetTableName(cloudSyncer->GetCurrentContextTableName()); auto token = new (std::nothrow) SQLiteSingleVerRelationalContinueToken(syncTimeRange, queryObject); ContinueToken conStmtToken = static_cast(token); delete token; - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillOnce([&conStmtToken, &uploadData2]( - const TableSchema &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { - continueStmtToken = conStmtToken; - cloudDataResult = uploadData2; - return -E_UNFINISHED; - }); + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillOnce([&conStmtToken, &uploadData2](const TableSchema &, + const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { + continueStmtToken = conStmtToken; + cloudDataResult = uploadData2; + return -E_UNFINISHED; + }); CloudSyncData uploadData3(cloudSyncer->GetCurrentContextTableName()); uploadData3.insData.record = std::vector(1001, tmp); @@ -440,7 +441,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck008, TestSize.Level1 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, ReleaseCloudDataToken(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 1000; return E_OK; }); @@ -454,8 +455,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck008, TestSize.Level1 cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); uploadData2.insData.record = std::vector(100); uploadData2.insData.extend = std::vector(100); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData2](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData2](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData2; return -E_UNFINISHED; @@ -499,7 +500,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck009, TestSize.Level1 EXPECT_CALL(*idb, BatchUpdate(_, _, _)).WillRepeatedly(Return(OK)); EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 10000; return E_OK; }); @@ -507,8 +508,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck009, TestSize.Level1 CloudSyncData uploadData(cloudSyncer->GetCurrentContextTableName()); uploadData.insData.record = std::vector(1000, tmp); uploadData.insData.extend = std::vector(1000, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; @@ -520,8 +521,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck009, TestSize.Level1 cloudSyncer->CallClearCloudSyncData(uploadData); uploadData.insData.record = std::vector(1000, tmp); uploadData.insData.extend = std::vector(999, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; @@ -563,7 +564,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck017, TestSize.Level1 EXPECT_CALL(*idb, BatchUpdate(_, _, _)).WillRepeatedly(Return(OK)); EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 10000; return E_OK; }); @@ -572,8 +573,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck017, TestSize.Level1 CloudSyncData uploadData2(cloudSyncer->GetCurrentContextTableName() + "abc"); uploadData2.insData.record = std::vector(1000, tmp); uploadData2.insData.extend = std::vector(1000, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData2](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData2](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData2; return E_OK; @@ -609,8 +610,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck010, TestSize.Level1 CloudSyncData uploadData(cloudSyncer->GetCurrentContextTableName()); cloudSyncer->initFullCloudSyncData(uploadData, 1000); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; @@ -619,7 +620,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck010, TestSize.Level1 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -670,7 +671,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck011, TestSize.Level1 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -691,8 +692,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck011, TestSize.Level1 uploadData2.updData.extend = std::vector(1000, tmp); uploadData2.delData.record = std::vector(1000, tmp); uploadData2.delData.extend = std::vector(1000, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData2](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([&uploadData2](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData2; return E_OK; @@ -733,7 +734,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck012, TestSize.Level1 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -754,17 +755,17 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck012, TestSize.Level1 uploadData3.insData.extend = std::vector(1000, tmp); uploadData3.delData.record = std::vector(1000, tmp); uploadData3.delData.extend = std::vector(1000, tmp); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData3](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillOnce([cloudSyncer, &uploadData3](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData3; return E_OK; }); - int errCode = cloudSyncer->CallDoUpload(6u); + int errCode = cloudSyncer->CallDoUpload(6u); // task id is 6 std::this_thread::sleep_for(std::chrono::seconds(1)); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(cloudSyncer->GetUploadSuccessCount(6u), 2000); - EXPECT_EQ(cloudSyncer->GetUploadFailCount(6u), 0); + EXPECT_EQ(cloudSyncer->GetUploadSuccessCount(6u), 2000); // task id is 6, success count is 2000 + EXPECT_EQ(cloudSyncer->GetUploadFailCount(6u), 0); // task id is 6 RuntimeContext::GetInstance()->StopTaskPool(); cloudSyncer->CallClose(); @@ -796,14 +797,14 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck013, TestSize.Level1 CloudSyncData uploadData(cloudSyncer->GetCurrentContextTableName()); cloudSyncer->initFullCloudSyncData(uploadData, 1000); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillRepeatedly([&uploadData](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillRepeatedly([&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; }); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillOnce([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillOnce([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -837,6 +838,12 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck013, TestSize.Level1 delete iCloud; } +void MockMethod014(MockICloudSyncStorageInterface *iCloud) +{ + CommonExpectCall(iCloud); + EXPECT_CALL(*iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); +} /** * @tc.name: UploadModeCheck014 * @tc.desc: Test case2 about upload when batch api are partially successful. @@ -853,20 +860,19 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck014, TestSize.Level1 cloudSyncer2->SetMockICloudDB(idb2); TaskId taskId = 8u; - CommonExpectCall(iCloud); - EXPECT_CALL(*iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); + MockMethod014(iCloud); // batch api partially success cloudSyncer2->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); CloudSyncData uploadData2(cloudSyncer2->GetCurrentContextTableName()); cloudSyncer2->initFullCloudSyncData(uploadData2, 1000); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillRepeatedly( - [&uploadData2](const TableSchema &, const Timestamp &, ContinueToken &, CloudSyncData &cloudDataResult) { + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillRepeatedly( + [&uploadData2](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &, + CloudSyncData &cloudDataResult) { cloudDataResult = uploadData2; return E_OK; }); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -918,14 +924,14 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck015, TestSize.Level1 cloudSyncer3->InitCloudSyncer(9u, SYNC_MODE_CLOUD_FORCE_PUSH); CloudSyncData uploadData3(cloudSyncer3->GetCurrentContextTableName()); cloudSyncer3->initFullCloudSyncData(uploadData3, 1000); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillRepeatedly([&uploadData3](const TableSchema &, const Timestamp &, ContinueToken &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillRepeatedly([&uploadData3](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData3; return E_OK; }); EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillOnce([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillOnce([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -1002,7 +1008,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck016, TestSize.Level1 CommonExpectCall(iCloud); // CheckSchema EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { + .WillRepeatedly([](const QuerySyncObject &, const Timestamp &, const bool, int64_t & count) { count = 3000; return E_OK; }); @@ -1011,8 +1017,8 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck016, TestSize.Level1 cloudSyncer->initFullCloudSyncData(uploadData, 1000); EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillRepeatedly([&uploadData](const TableSchema &, const Timestamp &, + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)) + .WillRepeatedly([&uploadData](const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { cloudDataResult = uploadData; return E_OK; @@ -1038,12 +1044,17 @@ void MockCall(MockICloudSyncStorageInterface *iCloud, const std::shared_ptr &idb) +{ + CommonExpectCall(iCloud); + MockCall(iCloud, idb); +} /** * @tc.name: UploadModeCheck018 * @tc.desc: Test notify count when upload with two batch @@ -1060,9 +1071,7 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck018, TestSize.Level1 auto idb = std::make_shared(); cloudSyncer->SetMockICloudDB(idb); cloudSyncer->InitCloudSyncer(5u, SYNC_MODE_CLOUD_FORCE_PUSH); - - CommonExpectCall(iCloud); - MockCall(iCloud, idb); + PrepareEnv018(iCloud, idb); // Batch_n CloudSyncData quantity > total count VBucket tmp = { pair(CloudDbConstant::MODIFY_FIELD, 1), @@ -1078,8 +1087,9 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck018, TestSize.Level1 auto token = new (std::nothrow) SQLiteSingleVerRelationalContinueToken(syncTimeRange, queryObject); auto conStmtToken = static_cast(token); delete token; - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)).WillOnce([&conStmtToken, &uploadData2]( - const TableSchema &, const Timestamp &, ContinueToken &continueStmtToken, CloudSyncData &cloudDataResult) { + EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _, _)).WillOnce([&conStmtToken, &uploadData2]( + const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &continueStmtToken, + CloudSyncData &cloudDataResult) { cloudDataResult = uploadData2; continueStmtToken = conStmtToken; return -E_UNFINISHED; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_compound_primary_key_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_compound_primary_key_sync_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fac9fef34de1e4ec8bf0258b643f852e82434b78 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_compound_primary_key_sync_test.cpp @@ -0,0 +1,312 @@ +/* + * 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. + */ +#ifdef RELATIONAL_STORE +#include +#include +#include "cloud/cloud_storage_utils.h" +#include "cloud_db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "process_system_api_adapter_impl.h" +#include "relational_store_instance.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "sqlite_relational_store.h" +#include "sqlite_relational_utils.h" +#include "store_observer.h" +#include "time_helper.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" +#include "virtual_cloud_db.h" +#include "mock_asset_loader.h" +#include "cloud_db_sync_utils_test.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + string g_storeID = "Relational_Store_SYNC"; + const string g_tableName = "worker"; + const string DB_SUFFIX = ".db"; + const string CLOUD = "cloud"; + string g_testDir; + string g_storePath; + std::shared_ptr g_virtualCloudDb; + std::shared_ptr g_virtualAssetLoader; + RelationalStoreObserverUnitTest *g_observer = nullptr; + RelationalStoreDelegate *g_delegate = nullptr; + const std::vector g_tables = {g_tableName}; + const std::string CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL = + "CREATE TABLE IF NOT EXISTS " + g_tableName + "(" \ + "name TEXT," \ + "height REAL ," \ + "married BOOLEAN ," \ + "photo BLOB NOT NULL," \ + "asset BLOB," \ + "age INT," \ + "PRIMARY KEY (" \ + " name," \ + " age)" \ + ");"; + const std::vector g_cloudFiledCompoundPrimaryKey = { + {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, + {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, + {"asset", TYPE_INDEX}, {"age", TYPE_INDEX, true} + }; + + void InitExpectChangedData(ChangedDataType dataType, int64_t count, ChangeType changeType) + { + ChangedData changedDataForTable; + changedDataForTable.tableName = g_tableName; + changedDataForTable.type = dataType; + changedDataForTable.field.push_back(std::string("rowid")); + changedDataForTable.field.push_back(std::string("name")); + changedDataForTable.field.push_back(std::string("age")); + for (int64_t i = 0; i < count; ++i) { + changedDataForTable.primaryData[changeType].push_back({i + 1, + "Cloud" + to_string(i), 13L}); // 13 is expect age + } + g_observer->SetExpectedResult(changedDataForTable); + } + + class DistributedDBCloudTableCompoundPrimaryKeySyncTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + protected: + sqlite3 *db = nullptr; + }; + + void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUpTestCase(void) + { + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + g_storePath = g_testDir + "/" + g_storeID + DB_SUFFIX; + LOGI("The test db is:%s", g_testDir.c_str()); + RuntimeConfig::SetCloudTranslate(std::make_shared()); + } + + void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDownTestCase(void) + {} + + void DistributedDBCloudTableCompoundPrimaryKeySyncTest::SetUp(void) + { + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + LOGD("Test dir is %s", g_testDir.c_str()); + db = RelationalTestUtils::CreateDataBase(g_storePath); + ASSERT_NE(db, nullptr); + CloudDBSyncUtilsTest::CreateUserDBAndTable(db, CREATE_LOCAL_TABLE_COMPOUND_PRIMARY_KEY_SQL); + CloudDBSyncUtilsTest::SetStorePath(g_storePath); + CloudDBSyncUtilsTest::InitSyncUtils(g_cloudFiledCompoundPrimaryKey, g_observer, g_virtualCloudDb, + g_virtualAssetLoader, g_delegate); + } + + void DistributedDBCloudTableCompoundPrimaryKeySyncTest::TearDown(void) + { + CloudDBSyncUtilsTest::CloseDb(g_observer, g_virtualCloudDb, g_delegate); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + } + +/* + * @tc.name: CloudSyncTest001 + * @tc.desc: test data sync when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_INSERT); + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest002 + * @tc.desc: test data sync when cloud update + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest002, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. update cloud data and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_UPDATE); + CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest003 + * @tc.desc: test data sync when cloud delete + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest003, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. delete cloud data and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_DELETE); + CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); +} + +/* + * @tc.name: CloudSyncTest004 + * @tc.desc: test asset when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_INSERT); + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest005 + * @tc.desc: test asset sync when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. update cloud asset and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_UPDATE); + CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest006 + * @tc.desc: test asset sync when cloud delete + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableCompoundPrimaryKeySyncTest, CloudSyncTest006, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. insert cloud asset and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_DELETE); + CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); +} + +} +#endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_without_primary_key_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_without_primary_key_sync_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86036a3c8cccc6bc4d3866c9d0c050fc807633d2 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_table_without_primary_key_sync_test.cpp @@ -0,0 +1,305 @@ +/* + * 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. + */ +#ifdef RELATIONAL_STORE +#include +#include +#include "cloud/cloud_storage_utils.h" +#include "cloud_db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "process_system_api_adapter_impl.h" +#include "relational_store_instance.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "sqlite_relational_store.h" +#include "sqlite_relational_utils.h" +#include "store_observer.h" +#include "time_helper.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" +#include "virtual_cloud_db.h" +#include "mock_asset_loader.h" +#include "cloud_db_sync_utils_test.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + string g_storeID = "Relational_Store_SYNC"; + const string g_tableName = "worker"; + const string DB_SUFFIX = ".db"; + const string CLOUD = "cloud"; + string g_testDir; + string g_storePath; + std::shared_ptr g_virtualCloudDb; + std::shared_ptr g_virtualAssetLoader; + RelationalStoreObserverUnitTest *g_observer = nullptr; + RelationalStoreDelegate *g_delegate = nullptr; + const std::vector g_tables = {g_tableName}; + const std::string CREATE_LOCAL_TABLE_WITHOUT_PRIMARY_KEY_SQL = + "CREATE TABLE IF NOT EXISTS " + g_tableName + "(" \ + "name TEXT," \ + "height REAL ," \ + "married BOOLEAN ," \ + "photo BLOB NOT NULL," \ + "asset BLOB," \ + "age INT);"; + const std::vector g_cloudFiledWithoutPrimaryKey = { + {"name", TYPE_INDEX, false, true}, {"height", TYPE_INDEX}, + {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, + {"asset", TYPE_INDEX}, {"age", TYPE_INDEX} + }; + + void InitExpectChangedData(ChangedDataType dataType, int64_t count, ChangeType changeType) + { + ChangedData changedDataForTable; + changedDataForTable.tableName = g_tableName; + changedDataForTable.type = dataType; + changedDataForTable.field.push_back(std::string("rowid")); + for (int64_t i = 1; i <= count; ++i) { + changedDataForTable.primaryData[changeType].push_back({i}); + } + g_observer->SetExpectedResult(changedDataForTable); + } + + class DistributedDBCloudTableWithoutPrimaryKeySyncTest : public testing::Test { + public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + protected: + sqlite3 *db = nullptr; + }; + + void DistributedDBCloudTableWithoutPrimaryKeySyncTest::SetUpTestCase(void) + { + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + g_storePath = g_testDir + "/" + g_storeID + DB_SUFFIX; + LOGI("The test db is:%s", g_testDir.c_str()); + RuntimeConfig::SetCloudTranslate(std::make_shared()); + } + + void DistributedDBCloudTableWithoutPrimaryKeySyncTest::TearDownTestCase(void) + {} + + void DistributedDBCloudTableWithoutPrimaryKeySyncTest::SetUp(void) + { + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + LOGD("Test dir is %s", g_testDir.c_str()); + db = RelationalTestUtils::CreateDataBase(g_storePath); + ASSERT_NE(db, nullptr); + CloudDBSyncUtilsTest::CreateUserDBAndTable(db, CREATE_LOCAL_TABLE_WITHOUT_PRIMARY_KEY_SQL); + CloudDBSyncUtilsTest::SetStorePath(g_storePath); + CloudDBSyncUtilsTest::InitSyncUtils(g_cloudFiledWithoutPrimaryKey, g_observer, g_virtualCloudDb, + g_virtualAssetLoader, g_delegate); + } + + void DistributedDBCloudTableWithoutPrimaryKeySyncTest::TearDown(void) + { + CloudDBSyncUtilsTest::CloseDb(g_observer, g_virtualCloudDb, g_delegate); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + } + +/* + * @tc.name: CloudSyncTest001 + * @tc.desc: test data sync when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_INSERT); + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest002 + * @tc.desc: test data sync when cloud update + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest002, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. update cloud data and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_UPDATE); + CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest003 + * @tc.desc: test data sync when cloud delete + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest003, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud data and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, true, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. delete cloud data and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::DATA, cloudCount, ChangeType::OP_DELETE); + CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); +} + +/* + * @tc.name: CloudSyncTest004 + * @tc.desc: test asset when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_INSERT); + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest005 + * @tc.desc: test asset sync when cloud insert + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. update cloud asset and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_UPDATE); + CloudDBSyncUtilsTest::UpdateCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); +} + +/* + * @tc.name: CloudSyncTest006 + * @tc.desc: test asset sync when cloud delete + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudTableWithoutPrimaryKeySyncTest, CloudSyncTest006, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud asset and merge + * @tc.expected: step1. check the changeddata and return ok + */ + int64_t cloudCount = 10; // 10 is random cloud count + int64_t paddingSize = 10; // 10 is padding size + CloudDBSyncUtilsTest::InsertCloudTableRecord(0, cloudCount, paddingSize, false, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckDownloadResult(db, {cloudCount}, CLOUD); + CloudDBSyncUtilsTest::CheckCloudTotalCount({cloudCount}, g_virtualCloudDb); + + /** + * @tc.steps:step2. insert cloud asset and merge + * @tc.expected: step2. check the changeddata and return ok + */ + InitExpectChangedData(ChangedDataType::ASSET, cloudCount, ChangeType::OP_DELETE); + CloudDBSyncUtilsTest::DeleteCloudTableRecordByGid(0, cloudCount, g_virtualCloudDb); + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + CloudDBSyncUtilsTest::CheckCloudTotalCount({0L}, g_virtualCloudDb); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + CloudDBSyncUtilsTest::CheckLocalRecordNum(db, g_tableName, 0); +} + +} +#endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h index 149e42ff7f4d7069be313c37cba1fd5f0a6eb24a..18072f3111baf064aaaf580b13ea7b2ddffa769e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h @@ -30,10 +30,12 @@ public: MOCK_METHOD1(StartTransaction, int(TransactType)); MOCK_METHOD0(Commit, int(void)); MOCK_METHOD0(Rollback, int(void)); - MOCK_METHOD4(GetUploadCount, int(const std::string &, const Timestamp &, const bool, int64_t &)); + MOCK_METHOD4(GetUploadCount, int(const QuerySyncObject &, const Timestamp &, bool, int64_t &)); MOCK_METHOD1(FillCloudGid, int(const CloudSyncData &)); - MOCK_METHOD4(GetCloudData, int(const TableSchema &, const Timestamp &, ContinueToken &, CloudSyncData &)); + MOCK_METHOD5(GetCloudData, int(const TableSchema &, const QuerySyncObject &, const Timestamp &, ContinueToken &, + CloudSyncData &)); MOCK_METHOD2(GetCloudDataNext, int(ContinueToken &, CloudSyncData &)); + MOCK_METHOD4(GetCloudGid, int(const TableSchema &, const QuerySyncObject &, bool, std::vector &)); MOCK_METHOD1(ReleaseCloudDataToken, int(ContinueToken &)); MOCK_METHOD4(GetInfoByPrimaryKeyOrGid, int(const std::string &, const VBucket &, DataInfoWithLog &, VBucket &)); MOCK_METHOD2(PutCloudSyncData, int(const std::string &, DownloadData &)); @@ -44,6 +46,7 @@ public: MOCK_METHOD1(SetLogTriggerStatus, int(bool)); MOCK_METHOD2(FillCloudGidAndAsset, int(OpType, const CloudSyncData &)); MOCK_CONST_METHOD0(GetIdentify, std::string()); + MOCK_METHOD1(CheckQueryValid, int(const QuerySyncObject &)); }; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp index e74d0d48a4fc8e24e1afd456dfa538bb995cbaea..944476ee97eb98f8fc16be32b61202c04d684abf 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp @@ -369,4 +369,12 @@ DBStatus VirtualCloudDb::GetDataStatus(const std::string &gid, bool &deleteStatu LOGE("not found gid %s ", gid.c_str()); return NOT_FOUND; } + +void VirtualCloudDb::ClearAllData() +{ + std::lock_guard autoLock(cloudDataMutex_); + cloudData_.clear(); + incrementCloudData_.clear(); + queryTimes_.clear(); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h index afaad573a85169c369b347d3a4e170f19d1a1df9..d54e6cd8e66339ddfa0d5ed775ceca62cfabe69b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h @@ -66,6 +66,8 @@ public: void SetActionStatus(DBStatus status); DBStatus GetDataStatus(const std::string &gid, bool &deleteStatus); + + void ClearAllData(); private: struct CloudData { VBucket record; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp index 231ff557f7540fe77899e9c8b8e8745a7adaa33d..279aa01601081c45fd84326b766ea6a034d525a2 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp @@ -55,35 +55,23 @@ void VirtualCloudSyncer::SetDownloadFunc(const std::function &function) void VirtualCloudSyncer::Notify(bool notifyIfError) { - TaskId currentTaskId; - { - std::lock_guard autoLock(contextLock_); - currentTaskId = currentContext_.currentTaskId; - } - CloudTaskInfo taskInfo; - { - std::lock_guard autoLock(queueLock_); - taskInfo = cloudTaskInfos_[currentTaskId]; - } - std::lock_guard autoLock(contextLock_); + std::lock_guard autoLock(dataLock_); + CloudTaskInfo taskInfo = cloudTaskInfos_[currentContext_.currentTaskId]; currentContext_.notifier->NotifyProcess(taskInfo, {}, notifyIfError); } size_t VirtualCloudSyncer::GetQueueCount() { - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); return taskQueue_.size(); } void VirtualCloudSyncer::SetCurrentTaskInfo(const SyncProcessCallback &callback, CloudSyncer::TaskId taskId) { - { - std::lock_guard autoContextLock(contextLock_); - currentContext_.currentTaskId = taskId; - currentContext_.notifier = std::make_shared(this); - } - std::lock_guard autoLock(queueLock_); + std::lock_guard autoLock(dataLock_); + currentContext_.currentTaskId = taskId; + currentContext_.notifier = std::make_shared(this); CloudTaskInfo taskInfo; taskInfo.callback = callback; cloudTaskInfos_[taskId] = taskInfo; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index 884911bf8ac7632bc57970e8627525f2813e47aa..dc1518ff4029a09ef0e5a9b7746b98aecb0d09e4 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -1739,9 +1739,10 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer004, TestSize.Level0) * @tc.expected: step2. data change device is deviceB */ EXPECT_EQ(observer->GetCallCount(), 1u); - EXPECT_EQ(g_observer->GetCallCount(), 0u); + EXPECT_EQ(g_observer->GetCallCount(), 1u); // support multi observer for one delegate EXPECT_EQ(observer->GetDataChangeDevice(), DEVICE_B); CheckIdentify(observer); + delete observer; } /* @@ -1926,12 +1927,13 @@ void RegisterNewObserver(RelationalStoreDelegate *rdb1, RelationalStoreObserverU InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 2); // 2 is watermark Query query = Query::Select(g_tableName); EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK); - EXPECT_EQ(observer1->GetCallCount(), 0u); + EXPECT_EQ(observer1->GetCallCount(), 1u); // one delegate can register 8 observer EXPECT_EQ(autoLaunchObserver->GetCallCount(), 2u); // 2 is auto_launch observer triggered times EXPECT_EQ(observer2->GetCallCount(), 1u); EXPECT_EQ(rdb1->UnRegisterObserver(), OK); observer2->ResetToZero(); + observer1->ResetToZero(); InsertDataToDeviceB(dataMap, g_tableName, g_fieldInfoList, 3); // 3 is watermark EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK); EXPECT_EQ(observer1->GetCallCount(), 0u); diff --git a/kv_store/interfaces/CMakeLists.txt b/kv_store/interfaces/CMakeLists.txt index c9f2f60ac66fbc93c1ed8fb42baace5dc8ddc2cd..ee079ea40aeb0fe00e35d811f421a8ae82faa0c5 100644 --- a/kv_store/interfaces/CMakeLists.txt +++ b/kv_store/interfaces/CMakeLists.txt @@ -4,5 +4,6 @@ include_directories(${KV_STORE_DIR}/frameworks/libs/distributeddb/interfaces/inc include_directories(${KV_STORE_DIR}/frameworks/common) include_directories(${KV_STORE_DIR}/frameworks/innerkitsimpl/distributeddatafwk/include) include_directories(${KV_STORE_DIR}/frameworks/innerkitsimpl/distributeddatafwk/src) +include_directories(${KV_STORE_DIR}/frameworks/innerkitsimpl/distributeddatasvc/include) include_directories(${KV_STORE_DIR}/frameworks/innerkitsimpl/kvdb/include) include_directories(${KV_STORE_DIR}/interfaces/innerkits/distributeddata/include) diff --git a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn index d1b75214777e4f90313a21a7853d327fe06b8e8f..836faa33cf5dc135649f2e66c447c64a3573b2ee 100644 --- a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn +++ b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn @@ -15,7 +15,10 @@ import("//foundation/distributeddatamgr/data_share/datashare.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") group("build_module") { - deps = [ ":distributeddata_inner" ] + deps = [] + if (!use_platform_win && !use_platforn_mac) { + deps += [ ":distributeddata_inner" ] + } } config("distributeddatafwk_config") { diff --git a/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h b/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h index d87a7a2dfb2dded88fcdbf5d496d40b986a0fbec..93280684c41fd268c545af850fb7fb0036576d61 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/distributed_kv_data_manager.h @@ -17,6 +17,7 @@ #define DISTRIBUTED_KV_DATA_MANAGER_H #include +#include "executor_pool.h" #include "kvstore.h" #include "kvstore_death_recipient.h" #include "kvstore_observer.h" @@ -147,6 +148,12 @@ public: * @param deathRecipient The pointer of the observer. */ API_EXPORT void UnRegisterKvStoreServiceDeathRecipient(std::shared_ptr deathRecipient); + + /** + * @brief Set executors to kv client. + * @param executors The executors. + */ + API_EXPORT void SetExecutors(std::shared_ptr executors); }; } // namespace DistributedKv } // namespace OHOS diff --git a/kv_store/frameworks/common/executor.h b/kv_store/interfaces/innerkits/distributeddata/include/executor.h similarity index 99% rename from kv_store/frameworks/common/executor.h rename to kv_store/interfaces/innerkits/distributeddata/include/executor.h index 56adc735f43024bdf24210fc9ed862f3afdbb042..e6bf0f10e4df0b7bfceaa8c26467edd5f5762234 100644 --- a/kv_store/frameworks/common/executor.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/executor.h @@ -19,10 +19,9 @@ #include #include #include - #include "priority_queue.h" -namespace OHOS { +namespace OHOS { class Executor : public std::enable_shared_from_this { public: using TaskId = uint64_t; diff --git a/kv_store/frameworks/common/executor_pool.h b/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h similarity index 96% rename from kv_store/frameworks/common/executor_pool.h rename to kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h index c94ee96a76ddf4fd59754e16b12691c7bb74b10f..309e562f426e9b3f06ee4343c474409bddd2a6a0 100644 --- a/kv_store/frameworks/common/executor_pool.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_EXECUTOR_POOL_H -#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_EXECUTOR_POOL_H +#ifndef OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_EXECUTOR_POOL_H +#define OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_EXECUTOR_POOL_H #include #include #include @@ -217,4 +217,5 @@ private: std::atomic taskId_; }; } // namespace OHOS -#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_EXECUTOR_POOL_H + +#endif // OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_EXECUTOR_POOL_H diff --git a/kv_store/frameworks/common/pool.h b/kv_store/interfaces/innerkits/distributeddata/include/pool.h similarity index 100% rename from kv_store/frameworks/common/pool.h rename to kv_store/interfaces/innerkits/distributeddata/include/pool.h diff --git a/kv_store/frameworks/common/priority_queue.h b/kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h similarity index 100% rename from kv_store/frameworks/common/priority_queue.h rename to kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h diff --git a/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn b/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn index 43db94ed9963f2fdfae495281af9a785619ccc1a..ef107a4ee029b9ba3c0d0403883e758d5b7b65bf 100644 --- a/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn +++ b/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn @@ -14,7 +14,10 @@ import("//build/ohos.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") group("build_module") { - deps = [ ":distributeddata_mgr" ] + deps = [] + if (!use_platform_win && !use_platforn_mac) { + deps += [ ":distributeddata_mgr" ] + } } config("data_mgr_public_config") { diff --git a/kv_store/kvstoremock/interfaces/innerkits/distributeddata/BUILD.gn b/kv_store/kvstoremock/interfaces/innerkits/distributeddata/BUILD.gn index 03f6d331a186950e43a0dcc2973de06756b65805..886afe7696f30ada5fa7f33fa091449b9023bea3 100644 --- a/kv_store/kvstoremock/interfaces/innerkits/distributeddata/BUILD.gn +++ b/kv_store/kvstoremock/interfaces/innerkits/distributeddata/BUILD.gn @@ -32,9 +32,6 @@ config("distributeddatafwk_config") { "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src", "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/rdb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/rdb/src", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/object/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/src", "//utils/system/safwk/native/include", @@ -47,15 +44,21 @@ config("distributeddatafwk_config") { } config("distributeddatafwk_public_config") { - visibility = [ "//foundation/distributeddatamgr/kv_store:*" ] + visibility = [ ":*" ] + + cflags = [ "-Wno-unused-value" ] include_dirs = [ "include", - ".//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/rdb/include", - ".//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/object/include", ".//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", - "//commonlibrary/c_utils/base/include", ] + if (use_platform_win) { + defines = [ "IS_WINDOWS" ] + cflags += [ "-includewin_glibc.h" ] + } else if (use_platforn_mac) { + defines = [ "IS_MAC" ] + cflags += [ "-includemac_glibc.h" ] + } } ohos_shared_library("distributeddata_inner_mock") { @@ -91,6 +94,10 @@ ohos_shared_library("distributeddata_inner_mock") { "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", ] + configs = [ ":distributeddatafwk_config" ] + + public_configs = [ ":distributeddatafwk_public_config" ] + cflags_cc = [ "-std=c++17" ] ldflags = [ "-v" ] sources = [ @@ -115,6 +122,7 @@ ohos_shared_library("distributeddata_inner_mock") { deps = [ "//foundation/arkui/napi:ace_napi", "//foundation/distributeddatamgr/kv_store/kvstoremock/distributeddb:distributeddb_mock", + "//third_party/bounds_checking_function:libsec_static", "//third_party/jsoncpp:jsoncpp_static", "//third_party/libuv:uv", "//third_party/sqlite:sqlite_sdk", @@ -122,11 +130,14 @@ ohos_shared_library("distributeddata_inner_mock") { if (use_platform_win) { defines = [ "IS_WINDOWS" ] + sources += [ "../../../interfaces/mock/win_glibc.cpp" ] deps += [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_windows", ] } else if (use_platforn_mac) { defines = [ "IS_MAC" ] + sources += [ "../../../interfaces/mock/mac_glibc.cpp" ] + include_dirs += [ "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/relational", diff --git a/kv_store/kvstoremock/interfaces/jskits/distributeddata/BUILD.gn b/kv_store/kvstoremock/interfaces/jskits/distributeddata/BUILD.gn index e40610e1e84467e4b655e1f62dd30d88fc79d2b5..3506bdf6f1c05daeabeaaaa3da0e2a141eac7ad2 100644 --- a/kv_store/kvstoremock/interfaces/jskits/distributeddata/BUILD.gn +++ b/kv_store/kvstoremock/interfaces/jskits/distributeddata/BUILD.gn @@ -67,8 +67,9 @@ if (use_platform_win || use_platforn_mac) { ] deps = [ + "${kv_store_base_path}/kvstoremock/interfaces/innerkits/distributeddata:distributeddata_inner_mock", "//foundation/arkui/napi:ace_napi", - "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/innerkits/distributeddata:distributeddata_inner_mock", + "//third_party/bounds_checking_function:libsec_static", "//third_party/libuv:uv", ] diff --git a/kv_store/kvstoremock/interfaces/jskits/distributedkvstore/BUILD.gn b/kv_store/kvstoremock/interfaces/jskits/distributedkvstore/BUILD.gn index b46ff4533aad47a056f77cb3a85e066840297bdc..6c0b9d29c75a6636c8a8805d30b8a6138266e212 100644 --- a/kv_store/kvstoremock/interfaces/jskits/distributedkvstore/BUILD.gn +++ b/kv_store/kvstoremock/interfaces/jskits/distributedkvstore/BUILD.gn @@ -72,8 +72,9 @@ if (use_platform_win || use_platforn_mac) { ] deps = [ + "${kv_store_base_path}/kvstoremock/interfaces/innerkits/distributeddata:distributeddata_inner_mock", "//foundation/arkui/napi:ace_napi", - "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/innerkits/distributeddata:distributeddata_inner_mock", + "//third_party/bounds_checking_function:libsec_static", "//third_party/libuv:uv", ] diff --git a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.h b/kv_store/kvstoremock/interfaces/mock/mac_glibc.cpp similarity index 68% rename from datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.h rename to kv_store/kvstoremock/interfaces/mock/mac_glibc.cpp index 9c3ae6e0bed767b265be8250981368aa0649f67b..82921af19506a92f0c69c8303f959336b2436f00 100644 --- a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/schemaquery_fuzzer.h +++ b/kv_store/kvstoremock/interfaces/mock/mac_glibc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef SCHEMAQUERY_H -#define SCHEMAQUERY_H - -#define FUZZ_PROJECT_NAME "SchemaQuery_fuzzer" - -#endif // SCHEMAQUERY_H \ No newline at end of file +#include "mac_glibc.h" +namespace OHOS { +__attribute__((visibility("default"))) int pthread_setname_np(std::thread::native_handle_type tid, const char *name) +{ + (void) tid; + return ::pthread_setname_np(name); +} +} diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp b/kv_store/kvstoremock/interfaces/mock/mac_glibc.h similarity index 75% rename from datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp rename to kv_store/kvstoremock/interfaces/mock/mac_glibc.h index 54fc55458f0c4f40d03ab5175cdee2c236e9dad5..70f0700d42cc88c53ad0432f5a1ca79ef7bef699 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.cpp +++ b/kv_store/kvstoremock/interfaces/mock/mac_glibc.h @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "clean_after_get.h" - +#ifndef MAC_GLIBC_H +#define MAC_GLIBC_H +#include namespace OHOS { -namespace UDMF { -} // namespace UDMF -} // namespace OHOS \ No newline at end of file +__attribute__((visibility("default"))) int pthread_setname_np(std::thread::native_handle_type tid, const char *name); +} +#endif // MAC_GLIBC_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h b/kv_store/kvstoremock/interfaces/mock/win_glibc.cpp similarity index 72% rename from datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h rename to kv_store/kvstoremock/interfaces/mock/win_glibc.cpp index 1e94b5fbd98af7ab344021cd06ff917d218b99a5..08f15ddbfd3cec06c4ad61e13da6a786458423ce 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/clean_after_get.h +++ b/kv_store/kvstoremock/interfaces/mock/win_glibc.cpp @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef UDMF_CLEAN_AFTER_GET_H -#define UDMF_CLEAN_AFTER_GET_H -#include "lifecycle_policy.h" - +#include "win_glibc.h" namespace OHOS { -namespace UDMF { -class CleanAfterGet : public LifeCyclePolicy { -public: -}; -} // namespace UDMF -} // namespace OHOS -#endif // UDMF_CLEAN_AFTER_GET_H +__attribute__((visibility("default"))) int pthread_setname_np(int tid, const char *name) +{ + return 0; +} + +__attribute__((visibility("default"))) int pthread_self() +{ + return 0; +} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/corpus/init b/kv_store/kvstoremock/interfaces/mock/win_glibc.h similarity index 65% rename from datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/corpus/init rename to kv_store/kvstoremock/interfaces/mock/win_glibc.h index 2f20d95e05f2a7d94f3ac5d1eb0288a5f3e3965e..be528b313b533fed75b8e24e00c69c4be669ad87 100644 --- a/datamgr_service/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/corpus/init +++ b/kv_store/kvstoremock/interfaces/mock/win_glibc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 @@ -12,5 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -FUZZ \ No newline at end of file +#ifndef WIN_GLIBC_H +#define WIN_GLIBC_H +#include +namespace OHOS { +__attribute__((visibility("default"))) int pthread_setname_np(int tid, const char *name); +__attribute__((visibility("default"))) int pthread_self(); +} +#endif // WIN_GLIBC_H \ No newline at end of file diff --git a/mock/innerkits/ability_runtime/runtime/include/js_runtime.h b/mock/innerkits/ability_runtime/runtime/include/js_runtime.h index 90e96a77eca0f83eb056b10f59dfde301aafb35f..0e23da1c5d988d385a06cccf5d7c426b7a8dd483 100644 --- a/mock/innerkits/ability_runtime/runtime/include/js_runtime.h +++ b/mock/innerkits/ability_runtime/runtime/include/js_runtime.h @@ -49,7 +49,7 @@ using AppLibPathMap = std::map>; namespace AbilityRuntime { class TimerTask; -inline void *DetachCallbackFunc(NativeEngine *engine, void *value, void *) +inline void *DetachCallbackFunc(napi_env env, void *value, void *) { return value; } @@ -58,9 +58,6 @@ class JsRuntime : public Runtime { public: static std::unique_ptr Create(const Options& options); - static std::unique_ptr LoadSystemModuleByEngine(NativeEngine* engine, - const std::string& moduleName, NativeValue* const* argv, size_t argc); - static void SetAppLibPath(const AppLibPathMap& appLibPaths, const bool& isSystemApp = false); static bool ReadSourceMapData(const std::string& hapPath, const std::string& sourceMapPath, std::string& content); @@ -69,31 +66,59 @@ public: ~JsRuntime() override; NativeEngine& GetNativeEngine() const; + napi_env GetNapiEnv() const; Language GetLanguage() const override { return Language::JS; } - std::unique_ptr LoadModule(const std::string& moduleName, const std::string& modulePath, - const std::string& hapPath, bool esmodule = false, bool useCommonChunk = false); - std::unique_ptr LoadSystemModule( - const std::string& moduleName, NativeValue* const* argv = nullptr, size_t argc = 0); void PostTask(const std::function& task, const std::string& name, int64_t delayTime); + void PostSyncTask(const std::function& task, const std::string& name); void RemoveTask(const std::string& name); void DumpHeapSnapshot(bool isPrivate) override; + bool BuildJsStackInfoList(uint32_t tid, std::vector& jsFrames) override; void NotifyApplicationState(bool isBackground) override; + bool SuspendVM(uint32_t tid) override; + void ResumeVM(uint32_t tid) override; + + bool RunSandboxScript(const std::string& path, const std::string& hapPath); + bool RunScript(const std::string& path, const std::string& hapPath, bool useCommonChunk = false); void PreloadSystemModule(const std::string& moduleName) override; - void UpdateExtensionType(int32_t extensionType) override; void StartDebugMode(bool needBreakPoint) override; void StopDebugMode(); bool LoadRepairPatch(const std::string& hqfFile, const std::string& hapPath) override; bool UnLoadRepairPatch(const std::string& hqfFile) override; bool NotifyHotReloadPage() override; + void RegisterUncaughtExceptionHandler(const JsEnv::UncaughtExceptionInfo& uncaughtExceptionInfo); + bool LoadScript(const std::string& path, std::vector* buffer = nullptr, bool isBundle = false); + bool LoadScript(const std::string& path, uint8_t* buffer, size_t len, bool isBundle); + bool StartDebugger(bool needBreakPoint, uint32_t instanceId); + void StopDebugger(); + NativeEngine* GetNativeEnginePointer() const; + panda::ecmascript::EcmaVM* GetEcmaVm() const; + + void UpdateModuleNameAndAssetPath(const std::string& moduleName); void RegisterQuickFixQueryFunc(const std::map& moduleAndPath) override; + static bool GetFileBuffer(const std::string& filePath, std::string& fileFullName, std::vector& buffer); + + void InitSourceMap(const std::shared_ptr operatorImpl); void FreeNativeReference(std::unique_ptr reference); + void FreeNativeReference(std::shared_ptr&& reference); + void StartProfiler(const std::string &perfCmd) override; + + void ReloadFormComponent(); // Reload ArkTS-Card component + void DoCleanWorkAfterStageCleaned() override; + void SetModuleLoadChecker(const std::shared_ptr& moduleCheckerDelegate) const override; + + static std::unique_ptr LoadSystemModuleByEngine(napi_env env, + const std::string& moduleName, const napi_value* argv, size_t argc); + std::unique_ptr LoadModule(const std::string& moduleName, const std::string& modulePath, + const std::string& hapPath, bool esmodule = false, bool useCommonChunk = false); + std::unique_ptr LoadSystemModule( + const std::string& moduleName, const napi_value* argv = nullptr, size_t argc = 0); private: void FinishPreload() override; @@ -101,8 +126,10 @@ private: bool Initialize(const Options& options); void Deinitialize(); - NativeValue* LoadJsBundle(const std::string& path, const std::string& hapPath, bool useCommonChunk = false); - NativeValue* LoadJsModule(const std::string& path, const std::string& hapPath); + int32_t JsperfProfilerCommandParse(const std::string &command, int32_t defaultValue); + + napi_value LoadJsBundle(const std::string& path, const std::string& hapPath, bool useCommonChunk = false); + napi_value LoadJsModule(const std::string& path, const std::string& hapPath); bool debugMode_ = false; bool preloaded_ = false; @@ -110,19 +137,28 @@ private: std::string codePath_; std::string moduleName_; std::unique_ptr methodRequireNapiRef_; - std::shared_ptr eventHandler_; std::unordered_map modules_; std::shared_ptr jsEnv_ = nullptr; - + uint32_t instanceId_ = 0; std::string bundleName_; + int32_t apiTargetVersion_ = 0; + + static std::atomic hasInstance; + private: bool CreateJsEnv(const Options& options); void PreloadAce(const Options& options); - bool InitLoop(const std::shared_ptr& eventRunner); + bool InitLoop(); inline bool IsUseAbilityRuntime(const Options& options) const; void FreeNativeReference(std::unique_ptr uniqueNativeRef, - std::shared_ptr&& sharedNativeRef); + std::shared_ptr&& sharedNativeRef); + void InitConsoleModule(); void InitTimerModule(); + void InitWorkerModule(const Options& options); + void ReInitJsEnvImpl(const Options& options); + void PostPreload(const Options& options); + void LoadAotFile(const Options& options); + void SetRequestAotCallback(); }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/mock/innerkits/ability_runtime/runtime/include/js_runtime_utils.h b/mock/innerkits/ability_runtime/runtime/include/js_runtime_utils.h index 6ea21aa6d2218c099af54c854681321b09a9bcdb..48a978140c259bfc8fb900f1639bf5d4333bf0af 100644 --- a/mock/innerkits/ability_runtime/runtime/include/js_runtime_utils.h +++ b/mock/innerkits/ability_runtime/runtime/include/js_runtime_utils.h @@ -1,205 +1,306 @@ /* - * Copyright (c) 2021 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 FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H -#define FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H +* Copyright (c) 2021-2022 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 OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H +#define OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H #include #include +#include #include -#include "js_runtime.h" -#include "native_engine/native_value.h" +#include "napi/native_api.h" #include "native_engine/native_engine.h" + +#include "js_runtime.h" + namespace OHOS { namespace AbilityRuntime { -template -inline T* ConvertNativeValueTo(NativeValue* value) -{ - return (value != nullptr) ? static_cast(value->GetInterface(T::INTERFACE_ID)) : nullptr; -} +constexpr size_t ARGC_MAX_COUNT = 10; + +#define NAPI_CALL_NO_THROW(theCall, retVal) \ + do { \ + if ((theCall) != napi_ok) { \ + return retVal; \ + } \ + } while (0) + +#define GET_CB_INFO_AND_CALL(env, info, T, func) \ + do { \ + size_t argc = ARGC_MAX_COUNT; \ + napi_value argv[ARGC_MAX_COUNT] = {nullptr}; \ + T* me = static_cast(GetCbInfoFromCallbackInfo(env, info, &argc, argv)); \ + return (me != nullptr) ? me->func(env, argc, argv) : nullptr; \ + } while (0) + +struct NapiCallbackInfo { + size_t argc = ARGC_MAX_COUNT; + napi_value argv[ARGC_MAX_COUNT] = {nullptr}; + napi_value thisVar = nullptr; +}; + +#define GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, T, func, name) \ + do { \ + NapiCallbackInfo napiInfo; \ + T* me = static_cast(GetNapiCallbackInfoAndThis(env, info, napiInfo, name)); \ + return (me != nullptr) ? me->func(env, napiInfo) : nullptr; \ + } while (0) + +#define GET_NAPI_INFO_AND_CALL(env, info, T, func) \ + GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, T, func, nullptr) + +void* GetNapiCallbackInfoAndThis( + napi_env env, napi_callback_info info, NapiCallbackInfo& napiInfo, const char* name = nullptr); template inline constexpr size_t ArraySize(T (&)[N]) noexcept { - return N; + return N; +} + +inline napi_value CreateJsUndefined(napi_env env) +{ + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +inline napi_value CreateJsNull(napi_env env) +{ + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +inline napi_value CreateJsNumber(napi_env env, int32_t value) +{ + napi_value result = nullptr; + napi_create_int32(env, value, &result); + return result; +} + +inline napi_value CreateJsNumber(napi_env env, uint32_t value) +{ + napi_value result = nullptr; + napi_create_uint32(env, value, &result); + return result; +} + +inline napi_value CreateJsNumber(napi_env env, int64_t value) +{ + napi_value result = nullptr; + napi_create_int64(env, value, &result); + return result; +} + +inline napi_value CreateJsNumber(napi_env env, double value) +{ + napi_value result = nullptr; + napi_create_double(env, value, &result); + return result; } template -inline NativeValue* CreateJsValue(NativeEngine& engine, const T& value) +inline napi_value CreateJsValue(napi_env env, const T& value) +{ + using ValueType = std::remove_cv_t>; + napi_value result = nullptr; + if constexpr (std::is_same_v) { + napi_get_boolean(env, value, &result); + return result; + } else if constexpr (std::is_arithmetic_v) { + return CreateJsNumber(env, value); + } else if constexpr (std::is_same_v) { + napi_create_string_utf8(env, value.c_str(), value.length(), &result); + return result; + } else if constexpr (std::is_enum_v) { + return CreateJsNumber(env, static_cast>(value)); + } else if constexpr (std::is_same_v) { + (value != nullptr) ? napi_create_string_utf8(env, value, strlen(value), &result) : + napi_get_undefined(env, &result); + return result; + } +} + +inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int32_t& value) +{ + NAPI_CALL_NO_THROW(napi_get_value_int32(env, jsValue, &value), false); + return true; +} + +inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, uint32_t& value) { - using ValueType = std::remove_cv_t>; - if constexpr (std::is_same_v) { - return engine.CreateBoolean(value); - } else if constexpr (std::is_arithmetic_v) { - return engine.CreateNumber(value); - } else if constexpr (std::is_same_v) { - return engine.CreateString(value.c_str(), value.length()); - } else if constexpr (std::is_enum_v) { - return engine.CreateNumber(static_cast>(value)); - } - return engine.CreateUndefined(); + NAPI_CALL_NO_THROW(napi_get_value_uint32(env, jsValue, &value), false); + return true; +} + +inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, int64_t& value) +{ + NAPI_CALL_NO_THROW(napi_get_value_int64(env, jsValue, &value), false); + return true; +} + +inline bool ConvertFromJsNumber(napi_env env, napi_value jsValue, double& value) +{ + NAPI_CALL_NO_THROW(napi_get_value_double(env, jsValue, &value), false); + return true; } template -inline bool ConvertFromJsValue(NativeEngine& engine, NativeValue* jsValue, T& value) +inline bool ConvertFromJsValue(napi_env env, napi_value jsValue, T& value) { - if (jsValue == nullptr) { - return false; - } - - using ValueType = std::remove_cv_t>; - if constexpr (std::is_same_v) { - auto boolValue = ConvertNativeValueTo(jsValue); - if (boolValue == nullptr) { - return false; - } - value = *boolValue; - return true; - } else if constexpr (std::is_arithmetic_v) { - auto numberValue = ConvertNativeValueTo(jsValue); - if (numberValue == nullptr) { - return false; - } - value = *numberValue; - return true; - } else if constexpr (std::is_same_v) { - auto stringValue = ConvertNativeValueTo(jsValue); - if (stringValue == nullptr) { - return false; - } - size_t len = stringValue->GetLength() + 1; - auto buffer = std::make_unique(len); - size_t strLength = 0; - stringValue->GetCString(buffer.get(), len, &strLength); - value = buffer.get(); - return true; - } else if constexpr (std::is_enum_v) { - auto numberValue = ConvertNativeValueTo(jsValue); - if (numberValue == nullptr) { - return false; - } - value = static_cast(static_cast>(*numberValue)); - return true; - } + if (jsValue == nullptr) { + return false; + } + + using ValueType = std::remove_cv_t>; + if constexpr (std::is_same_v) { + NAPI_CALL_NO_THROW(napi_get_value_bool(env, jsValue, &value), false); + return true; + } else if constexpr (std::is_arithmetic_v) { + return ConvertFromJsNumber(env, jsValue, value); + } else if constexpr (std::is_same_v) { + size_t len = 0; + NAPI_CALL_NO_THROW(napi_get_value_string_utf8(env, jsValue, nullptr, 0, &len), false); + auto buffer = std::make_unique(len + 1); + size_t strLength = 0; + NAPI_CALL_NO_THROW(napi_get_value_string_utf8(env, jsValue, buffer.get(), len + 1, &strLength), false); + value = buffer.get(); + return true; + } else if constexpr (std::is_enum_v) { + std::make_signed_t numberValue = 0; + if (!ConvertFromJsNumber(env, jsValue, numberValue)) { + return false; + } + value = static_cast(numberValue); + return true; + } } template -NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector& data) +napi_value CreateNativeArray(napi_env env, const std::vector& data) { - NativeValue* arrayValue = engine.CreateArray(data.size()); - NativeArray* array = ConvertNativeValueTo(arrayValue); - uint32_t index = 0; - for (const T& item : data) { - array->SetElement(index++, CreateJsValue(engine, item)); - } - return arrayValue; + napi_value arrayValue = nullptr; + napi_create_array_with_length(env, data.size(), &arrayValue); + uint32_t index = 0; + for (const T& item : data) { + napi_set_element(env, arrayValue, index++, CreateJsValue(env, item)); + } + return arrayValue; } -NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string()); -void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name, NativeCallback func); -void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter); -void* GetNativePointerFromCallbackInfo(NativeEngine* engine, NativeCallbackInfo* info, const char* name); +napi_value CreateJsError(napi_env env, int32_t errCode, const std::string& message = std::string()); +void BindNativeFunction(napi_env env, napi_value object, const char* name, + const char* moduleName, napi_callback func); +void BindNativeProperty(napi_env env, napi_value object, const char* name, napi_callback getter); +void* GetNativePointerFromCallbackInfo(napi_env env, napi_callback_info info, const char* name); +void* GetCbInfoFromCallbackInfo(napi_env env, napi_callback_info info, size_t* argc, napi_value* argv); void SetNamedNativePointer( - NativeEngine& engine, NativeObject& object, const char* name, void* ptr, NativeFinalize func); -void* GetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name); + napi_env env, napi_value object, const char* name, void* ptr, napi_finalize func); +void* GetNamedNativePointer(napi_env env, napi_value object, const char* name); + +bool CheckTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType); template -T* CheckParamsAndGetThis(NativeEngine* engine, NativeCallbackInfo* info, const char* name = nullptr) +T* CheckParamsAndGetThis(napi_env env, napi_callback_info info, const char* name = nullptr) { - return static_cast(GetNativePointerFromCallbackInfo(engine, info, name)); + return static_cast(GetNativePointerFromCallbackInfo(env, info, name)); } class HandleScope final { public: - explicit HandleScope(JsRuntime& jsRuntime); - explicit HandleScope(NativeEngine& engine); - ~HandleScope(); - - NativeValue* Escape(NativeValue* value); - - HandleScope(const HandleScope&) = delete; - HandleScope(HandleScope&&) = delete; - HandleScope& operator=(const HandleScope&) = delete; - HandleScope& operator=(HandleScope&&) = delete; + explicit HandleScope(JsRuntime& jsRuntime); + explicit HandleScope(napi_env env); + ~HandleScope(); + HandleScope(const HandleScope&) = delete; + HandleScope(HandleScope&&) = delete; + HandleScope& operator=(const HandleScope&) = delete; + HandleScope& operator=(HandleScope&&) = delete; private: -// NativeScopeManager* scopeManager_ = nullptr; -// NativeScope* nativeScope_ = nullptr; + napi_handle_scope scope_ = nullptr; + napi_env env_ = nullptr; }; class HandleEscape final { public: - explicit HandleEscape(JsRuntime& jsRuntime); - explicit HandleEscape(NativeEngine& engine); - ~HandleEscape(); + explicit HandleEscape(JsRuntime& jsRuntime); + explicit HandleEscape(napi_env env); + ~HandleEscape(); - NativeValue* Escape(NativeValue* value); - - HandleEscape(const HandleEscape&) = delete; - HandleEscape(HandleEscape&&) = delete; - HandleEscape& operator=(const HandleEscape&) = delete; - HandleEscape& operator=(HandleEscape&&) = delete; + napi_value Escape(napi_value value); + HandleEscape(const HandleEscape&) = delete; + HandleEscape(HandleEscape&&) = delete; + HandleEscape& operator=(const HandleEscape&) = delete; + HandleEscape& operator=(HandleEscape&&) = delete; private: -// NativeScopeManager* scopeManager_ = nullptr; -// NativeScope* nativeScope_ = nullptr; + napi_escapable_handle_scope scope_ = nullptr; + napi_env env_ = nullptr; }; -class AsyncTask final { +class NapiAsyncTask final { public: - using ExecuteCallback = std::function; - using CompleteCallback = std::function; - - static void Schedule(const std::string& name, NativeEngine& engine, std::unique_ptr&& task); + using ExecuteCallback = std::function; + using CompleteCallback = std::function; - AsyncTask(NativeDeferred* deferred, std::unique_ptr&& execute, - std::unique_ptr&& complete); - AsyncTask(NativeReference* callbackRef, std::unique_ptr&& execute, - std::unique_ptr&& complete); - ~AsyncTask(); + static void Schedule(const std::string& name, napi_env env, std::unique_ptr&& task); + static void ScheduleWithDefaultQos(const std::string &name, napi_env env, + std::unique_ptr&& task); + static void ScheduleHighQos(const std::string& name, napi_env env, std::unique_ptr&& task); + static void ScheduleLowQos(const std::string& name, napi_env env, std::unique_ptr&& task); + bool StartWithDefaultQos(const std::string &name, napi_env env); - void Resolve(NativeEngine& engine, NativeValue* value); - void Reject(NativeEngine& engine, NativeValue* error); + NapiAsyncTask(napi_deferred deferred, std::unique_ptr&& execute, + std::unique_ptr&& complete); + NapiAsyncTask(napi_ref callbackRef, std::unique_ptr&& execute, + std::unique_ptr&& complete); + ~NapiAsyncTask(); + void Resolve(napi_env env, napi_value value); + void Reject(napi_env env, napi_value error); + void ResolveWithNoError(napi_env env, napi_value value); + void ResolveWithCustomize(napi_env env, napi_value error, napi_value value); + void RejectWithCustomize(napi_env env, napi_value error, napi_value value); private: - static void Execute(NativeEngine* engine, void* data); - static void Complete(NativeEngine* engine, int32_t status, void* data); + static void Execute(napi_env env, void* data); + static void Complete(napi_env env, napi_status status, void* data); - bool Start(const std::string &name, NativeEngine& engine); + bool Start(const std::string &name, napi_env env); + bool StartHighQos(const std::string &name, napi_env env); + bool StartLowQos(const std::string &name, napi_env env); - std::unique_ptr deferred_; - std::unique_ptr callbackRef_; - std::unique_ptr work_; - std::unique_ptr execute_; - std::unique_ptr complete_; + napi_deferred deferred_ = nullptr; + napi_ref callbackRef_ = nullptr; + napi_async_work work_ = nullptr; + std::unique_ptr execute_; + std::unique_ptr complete_; }; -std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, - AsyncTask::ExecuteCallback&& execute, AsyncTask::CompleteCallback&& complete, NativeValue** result); +std::unique_ptr CreateAsyncTaskWithLastParam(napi_env env, napi_value lastParam, + NapiAsyncTask::ExecuteCallback&& execute, NapiAsyncTask::CompleteCallback&& complete, napi_value* result); -std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, - AsyncTask::ExecuteCallback&& execute, nullptr_t, NativeValue** result); +std::unique_ptr CreateAsyncTaskWithLastParam(napi_env env, napi_value lastParam, + NapiAsyncTask::ExecuteCallback&& execute, nullptr_t, napi_value* result); -std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, - nullptr_t, AsyncTask::CompleteCallback&& complete, NativeValue** result); +std::unique_ptr CreateAsyncTaskWithLastParam(napi_env env, napi_value lastParam, + nullptr_t, NapiAsyncTask::CompleteCallback&& complete, napi_value* result); -std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, - nullptr_t, nullptr_t, NativeValue** result); +std::unique_ptr CreateAsyncTaskWithLastParam(napi_env env, napi_value lastParam, + nullptr_t, nullptr_t, napi_value* result); } // namespace AbilityRuntime } // namespace OHOS - -#endif // FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H +#endif // OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H diff --git a/mock/innerkits/ability_runtime/runtime/include/runtime.h b/mock/innerkits/ability_runtime/runtime/include/runtime.h index 8280cbbe7b430b4c9a503a76d5fe70ea4e5d3c69..96fc0d2cb889a5bfc3e772c8edc35422a90c9f25 100644 --- a/mock/innerkits/ability_runtime/runtime/include/runtime.h +++ b/mock/innerkits/ability_runtime/runtime/include/runtime.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -13,11 +13,21 @@ * limitations under the License. */ -#ifndef FOUNDATION_OHOS_ABILITYRUNTIME_RUNTIME_H -#define FOUNDATION_OHOS_ABILITYRUNTIME_RUNTIME_H +#ifndef OHOS_ABILITY_RUNTIME_RUNTIME_H +#define OHOS_ABILITY_RUNTIME_RUNTIME_H -#include #include +#include +#include + +struct JsFrames { + std::string functionName; + std::string fileName; + std::string pos; + uintptr_t *nativePointer = nullptr; +}; + +class ModuleCheckerDelegate; namespace OHOS { namespace AppExecFwk { @@ -33,13 +43,32 @@ public: struct Options { Language lang = Language::JS; std::string bundleName; + std::string moduleName; std::string codePath; - std::string packagePath; + std::string bundleCodeDir; + std::string hapPath; + std::string arkNativeFilePath; + std::string packagePathStr; + std::vector assetBasePathStr; std::shared_ptr eventRunner; bool loadAce = true; + bool preload = false; + bool isBundle = true; + bool isDebugVersion = false; + bool isJsFramework = false; + bool isStageModel = true; + bool isTestFramework = false; + int32_t uid = -1; + // ArkTsCard start + bool isUnique = false; + // ArkTsCard end + std::shared_ptr moduleCheckerDelegate; + int32_t apiTargetVersion = 0; }; static std::unique_ptr Create(const Options& options); + static void SavePreloaded(std::unique_ptr&& instance); + static std::unique_ptr GetPreloaded(); Runtime() = default; virtual ~Runtime() = default; @@ -47,16 +76,20 @@ public: virtual Language GetLanguage() const = 0; virtual void StartDebugMode(bool needBreakPoint) = 0; -// virtual bool BuildJsStackInfoList(uint32_t tid, std::vector& jsFrames) = 0; + virtual bool BuildJsStackInfoList(uint32_t tid, std::vector& jsFrames) = 0; virtual void DumpHeapSnapshot(bool isPrivate) = 0; virtual void NotifyApplicationState(bool isBackground) = 0; + virtual bool SuspendVM(uint32_t tid) = 0; + virtual void ResumeVM(uint32_t tid) = 0; virtual void PreloadSystemModule(const std::string& moduleName) = 0; virtual void FinishPreload() = 0; virtual bool LoadRepairPatch(const std::string& patchFile, const std::string& baseFile) = 0; virtual bool NotifyHotReloadPage() = 0; virtual bool UnLoadRepairPatch(const std::string& patchFile) = 0; - virtual void UpdateExtensionType(int32_t extensionType) = 0; virtual void RegisterQuickFixQueryFunc(const std::map& moduleAndPath) = 0; + virtual void StartProfiler(const std::string &perfCmd) = 0; + virtual void DoCleanWorkAfterStageCleaned() = 0; + virtual void SetModuleLoadChecker(const std::shared_ptr& moduleCheckerDelegate) const {} Runtime(const Runtime&) = delete; Runtime(Runtime&&) = delete; @@ -65,4 +98,4 @@ public: }; } // namespace AbilityRuntime } // namespace OHOS -#endif // FOUNDATION_OHOS_ABILITYRUNTIME_RUNTIME_H +#endif // OHOS_ABILITY_RUNTIME_RUNTIME_H diff --git a/mock/innerkits/napi/native_engine/native_reference.h b/mock/innerkits/napi/native_engine/native_reference.h index 1d2f9e3647e7b8aa606b82896b0a9d1dbc903ba9..8aae3ce7ac4ea3298a90cc96d565db0f495622c1 100644 --- a/mock/innerkits/napi/native_engine/native_reference.h +++ b/mock/innerkits/napi/native_engine/native_reference.h @@ -1,17 +1,17 @@ /* - * Copyright (c) 2021 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. - */ +* Copyright (c) 2021 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 FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_REFERENCE_H #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_REFERENCE_H @@ -20,15 +20,31 @@ class NativeReference { public: - virtual ~NativeReference() {} - virtual uint32_t Ref() = 0; - virtual uint32_t Unref() = 0; - virtual NativeValue* Get() = 0; - virtual void* GetData() - { - return nullptr; - } - virtual operator NativeValue*() = 0; + virtual ~NativeReference() {} + virtual uint32_t Ref() = 0; + virtual uint32_t Unref() = 0; + virtual NativeValue* Get() = 0; + virtual void* GetData() + { + return nullptr; + } + virtual operator NativeValue*() + { + return nullptr; + } + virtual void SetDeleteSelf() {} + virtual uint32_t GetRefCount() + { + return 0; + } + virtual bool GetFinalRun() + { + return false; + } + virtual napi_value GetNapiValue() + { + return nullptr; + } }; #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_REFERENCE_H */ diff --git a/mock/kits/ability/ability_runtime/js_extension_context.h b/mock/kits/ability/ability_runtime/js_extension_context.h index 8dc434770b68b28cfb42979be71e509a85c40c38..303f08dbe532920c633403f6bc8c6f8d677de81f 100644 --- a/mock/kits/ability/ability_runtime/js_extension_context.h +++ b/mock/kits/ability/ability_runtime/js_extension_context.h @@ -37,9 +37,8 @@ private: std::weak_ptr context_; }; -NativeValue* CreateJsExtensionContext(NativeEngine& engine, const std::shared_ptr& context, - std::shared_ptr abilityInfo = nullptr, - DetachCallback detach = nullptr, AttachCallback attach = nullptr); +napi_value CreateJsExtensionContext(napi_env env, const std::shared_ptr& context, + std::shared_ptr abilityInfo = nullptr); } // namespace AbilityRuntime } // namespace OHOS #endif // ABILITY_RUNTIME_JS_EXTENSION_CONTEXT_H diff --git a/mock/src/mock_js_napi.cpp b/mock/src/mock_js_napi.cpp index ad5467e910ca0853b331ca4a20082ca113df2089..1b77acf1771458cc04f4606a16bc300367daf99f 100644 --- a/mock/src/mock_js_napi.cpp +++ b/mock/src/mock_js_napi.cpp @@ -15,6 +15,8 @@ #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" +#include "js_native_api.h" + #include extern "C" { napi_status napi_get_named_property(napi_env env, napi_value object, const char *utf8name, napi_value *result) @@ -375,4 +377,10 @@ NAPI_EXTERN napi_status napi_get_all_property_names(napi_env env, { return napi_ok; } -} \ No newline at end of file +} + +napi_status napi_add_finalizer(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, + void* finalize_hint, napi_ref* result) +{ + return napi_ok; +} diff --git a/mock/src/mock_js_runtime.cpp b/mock/src/mock_js_runtime.cpp index 0922bab710394671ce2decf130774102f336d962..479535210b0a9a7372a81d1c799014ca4020c15d 100644 --- a/mock/src/mock_js_runtime.cpp +++ b/mock/src/mock_js_runtime.cpp @@ -18,29 +18,22 @@ #include "extra_params.h" namespace OHOS::AbilityRuntime { HandleScope::HandleScope(JsRuntime& jsRuntime) {} -HandleScope::HandleScope(NativeEngine &engine) {} HandleScope::~HandleScope() {} -NativeValue* HandleScope::Escape(NativeValue* value) { return value; } HandleEscape::HandleEscape(JsRuntime& jsRuntime) {} -HandleEscape::HandleEscape(NativeEngine &engine) {} HandleEscape::~HandleEscape() {} -NativeValue* HandleEscape::Escape(NativeValue* value) { return value; } - -std::unique_ptr JsRuntime::LoadSystemModuleByEngine(NativeEngine *engine, - const std::string &moduleName, - NativeValue *const *argv, size_t argc) +napi_value HandleEscape::Escape(napi_value value) { - return std::unique_ptr(); + return nullptr; } std::unique_ptr JsRuntime::LoadModule(const std::string &moduleName, const std::string &modulePath, const std::string &hapPath, bool esmodule, bool useCommonChunk) { return std::unique_ptr(); } -std::unique_ptr JsRuntime::LoadSystemModule(const std::string &moduleName, NativeValue *const *argv, - size_t argc) +std::unique_ptr JsRuntime::LoadSystemModule( + const std::string& moduleName, const napi_value* argv, size_t argc) { - return std::unique_ptr(); + return nullptr; } NativeEngine& JsRuntime::GetNativeEngine() const { @@ -70,10 +63,12 @@ bool JsRuntime::UnLoadRepairPatch(const std::string &patchFile) { return false; } -void JsRuntime::UpdateExtensionType(int32_t extensionType) {} void JsRuntime::RegisterQuickFixQueryFunc(const std::map& moduleAndPath) {} +napi_env JsRuntime::GetNapiEnv() const +{ + return nullptr; +} -NativeValue* CreateJsExtensionContext(NativeEngine& engine, const std::shared_ptr& context, - std::shared_ptr abilityInfo, - DetachCallback detach, AttachCallback attach) { return nullptr; } +napi_value CreateJsExtensionContext(napi_env env, const std::shared_ptr& context, + std::shared_ptr abilityInfo) { return nullptr; } } diff --git a/preferences/CMakeLists.txt b/preferences/CMakeLists.txt index 55e0732c11b57c7873a83baf81475ed12efef35f..439ca095f2571d29cb3f0665c746f1d1329e49e4 100644 --- a/preferences/CMakeLists.txt +++ b/preferences/CMakeLists.txt @@ -23,7 +23,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/base/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/safwk/native/include) -include_directories(${KV_STORE_DIR}/frameworks/common) FIND_PACKAGE(LibXml2) IF (LibXml2_FOUND) @@ -36,7 +35,7 @@ ENDIF (LibXml2_FOUND) include_directories(${CMAKE_INCLUDE_PATH}/libxml2) include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) -set(links secure mock relational_store xml2) +set(links secure mock xml2) add_library(preferences SHARED ${preferences_src}) target_link_libraries(preferences ${links}) target_include_directories(preferences PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/include) \ No newline at end of file diff --git a/preferences/frameworks/common/include/log_print.h b/preferences/frameworks/common/include/log_print.h index c55f43e267e1d1cbd90ae48f1bba52b624d23f37..cdde63a8b26e1711d2d3f86f02abf787cb89248f 100644 --- a/preferences/frameworks/common/include/log_print.h +++ b/preferences/frameworks/common/include/log_print.h @@ -55,7 +55,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() const char *name = fileName.data(); \ auto pos = fileName.rfind('/'); \ pos = (pos != std::string::npos) ? pos + 1 : 0; \ - LOG_DEBUG(message " fileName is %{private}s.", name + pos); \ + LOG_DEBUG(message " fileName is %{private}s.", name + pos); \ } while (0) #define LOG_INFO(fmt, ...) \ diff --git a/preferences/frameworks/native/include/executor_pool.h b/preferences/frameworks/native/include/executor_pool.h index 7070bcb1ac01e62c71db5a4b951203c4e21279e4..76862e703b8c01c42d75f2501bd7352b338f683d 100644 --- a/preferences/frameworks/native/include/executor_pool.h +++ b/preferences/frameworks/native/include/executor_pool.h @@ -77,7 +77,6 @@ public: TaskId Execute(Task task) { if (poolStatus != Status::RUNNING) { - LOG_ERROR("execute task failed."); return INVALID_TASK_ID; } diff --git a/preferences/frameworks/native/include/preferences_impl.h b/preferences/frameworks/native/include/preferences_impl.h index 6bdf6c4ec0bc1cc285bdd2b309d6aa0bdf51eb2f..f2275bafc167fded4c30ea3ca8ff73ede0d37caa 100644 --- a/preferences/frameworks/native/include/preferences_impl.h +++ b/preferences/frameworks/native/include/preferences_impl.h @@ -155,6 +155,11 @@ public: int UnRegisterObserver(std::shared_ptr preferencesObserver, RegisterMode mode) override; + std::string GetGroupId() const override + { + return options_.dataGroupId; + } + static std::string MakeFilePath(const std::string &prefPath, const std::string &suffix); private: @@ -191,9 +196,8 @@ private: void AwaitLoadFile(); static void WriteToDiskFile(std::shared_ptr pref, std::shared_ptr mcr); bool CheckRequestValidForStateGeneration(std::shared_ptr mcr); - - bool ReadSettingXml(const std::string &prefPath, std::map &prefMap); - bool WriteSettingXml(const std::string &prefPath, const std::map &prefMap); + bool ReadSettingXml(std::shared_ptr pref); + bool WriteSettingXml(std::shared_ptr pref, const std::map &prefMap); bool loaded_; diff --git a/preferences/frameworks/native/include/preferences_xml_utils.h b/preferences/frameworks/native/include/preferences_xml_utils.h index 8c4bdef154e404e119e7564becc5141c30a281f0..7e4c805c6800cc762cb93c1d13e295bd5db686ae 100644 --- a/preferences/frameworks/native/include/preferences_xml_utils.h +++ b/preferences/frameworks/native/include/preferences_xml_utils.h @@ -31,8 +31,10 @@ public: class PreferencesXmlUtils { public: - static bool ReadSettingXml(const std::string &fileName, std::vector &settings); - static bool WriteSettingXml(const std::string &fileName, std::vector &settings); + static bool ReadSettingXml( + const std::string &fileName, const std::string &dataGroupId, std::vector &settings); + static bool WriteSettingXml( + const std::string &fileName, const std::string &dataGroupId, const std::vector &settings); static void LimitXmlPermission(const std::string &fileName); private: diff --git a/preferences/frameworks/native/include/priority_queue.h b/preferences/frameworks/native/include/priority_queue.h index 115031d32bad9a5c310006aae199facf204f2304..a93232bd31df8148950c82004f391e1d578253a8 100644 --- a/preferences/frameworks/native/include/priority_queue.h +++ b/preferences/frameworks/native/include/priority_queue.h @@ -15,6 +15,7 @@ #ifndef PREFERENCES_PRIORITY_QUEUE_H #define PREFERENCES_PRIORITY_QUEUE_H +#include #include #include #include diff --git a/preferences/frameworks/native/platform/include/preferences_file_lock.h b/preferences/frameworks/native/platform/include/preferences_file_lock.h index ddcb43f7c511380c1b513903c68ce26b0a3afe75..103545a3bf15eb94550959bbebdfcbe6c25df416 100644 --- a/preferences/frameworks/native/platform/include/preferences_file_lock.h +++ b/preferences/frameworks/native/platform/include/preferences_file_lock.h @@ -18,15 +18,15 @@ #include #include + #include "preferences_errno.h" namespace OHOS { namespace NativePreferences { class PreferencesFileLock final { public: - PreferencesFileLock(); + PreferencesFileLock(const std::string &path, const std::string &dataGroupId); ~PreferencesFileLock(); - int TryLock(const std::string &fileName); - int UnLock(); + private: int fd_{ -1 }; }; diff --git a/preferences/frameworks/native/platform/include/preferences_file_operation.h b/preferences/frameworks/native/platform/include/preferences_file_operation.h index 0709e7f35249abd7165af04dfb2f275aa996c510..8014b944a3e43070b64f47495dc57e7c970aef2d 100644 --- a/preferences/frameworks/native/platform/include/preferences_file_operation.h +++ b/preferences/frameworks/native/platform/include/preferences_file_operation.h @@ -15,14 +15,18 @@ #ifndef PREFERENCES_FILE_OPERATION_H #define PREFERENCES_FILE_OPERATION_H +#include #include #include + #include + #include "visibility.h" #if defined(WINDOWS_PLATFORM) #include +#include #else @@ -37,7 +41,7 @@ #endif #ifndef FILE_MODE -#define FILE_MODE 0771 +#define FILE_MODE 0770 #endif #ifndef FILE_EXIST @@ -67,6 +71,30 @@ static UNUSED_FUNCTION int Access(const std::string &filePath) return access(filePath.c_str(), FILE_EXIST); #endif } + +static UNUSED_FUNCTION bool Fsync(const std::string &filePath) +{ +#if defined(WINDOWS_PLATFORM) + int fd = _open(filePath.c_str(), _O_WRONLY, _S_IWRITE); + if (fd == -1) { + return false; + } + HANDLE handle = (HANDLE)_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE || !FlushFileBuffers(handle)) { + _close(fd); + return false; + } + _close(fd); +#else + int fd = open(filePath.c_str(), O_RDWR, S_IRUSR | S_IWUSR); + if (fd == -1 || fsync(fd) == -1) { + close(fd); + return false; + } + close(fd); +#endif + return true; +} } // namespace NativePreferences } // namespace OHOS #endif // PREFERENCES_FILE_OPERATION_H \ No newline at end of file diff --git a/preferences/frameworks/native/platform/src/preferences_file_lock.cpp b/preferences/frameworks/native/platform/src/preferences_file_lock.cpp index 6cbfe6bfa0ab4b4b508b9c167faa296bd8e7d55f..23bfb631172df4c2b80e6ff00ff9ec9763e5bc50 100644 --- a/preferences/frameworks/native/platform/src/preferences_file_lock.cpp +++ b/preferences/frameworks/native/platform/src/preferences_file_lock.cpp @@ -24,30 +24,32 @@ #include #include "log_print.h" +#include "visibility.h" namespace OHOS { namespace NativePreferences { +static UNUSED_FUNCTION std::string ExtractFileName(const std::string &path) +{ + auto pos = path.rfind('/'); + if (pos == std::string::npos) { + return path; + } + return path.substr(pos + 1); +} + #if !defined(WINDOWS_PLATFORM) static const std::chrono::microseconds WAIT_CONNECT_TIMEOUT(20); static const int ATTEMPTS = 5; -PreferencesFileLock::PreferencesFileLock() -{ -} - -PreferencesFileLock::~PreferencesFileLock() +PreferencesFileLock::PreferencesFileLock(const std::string &path, const std::string &dataGroupId) { - if (fd_ > 0) { - close(fd_); + if (dataGroupId.empty()) { + return; } -} - -int PreferencesFileLock::TryLock(const std::string &fileName) -{ - int fd = open(fileName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (fd == -1) { - LOG_ERROR("Couldn't open file %{public}s errno %{public}d.", fileName.c_str(), errno); - return (errno == EACCES) ? PERMISSION_DENIED : E_ERROR; + fd_ = open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (fd_ == -1) { + LOG_ERROR("Couldn't open file %{public}s errno %{public}d.", ExtractFileName(path).c_str(), errno); + return; } struct flock fileLockInfo = { 0 }; fileLockInfo.l_type = F_WRLCK; @@ -56,19 +58,18 @@ int PreferencesFileLock::TryLock(const std::string &fileName) fileLockInfo.l_len = 0; for (size_t i = 0; i < ATTEMPTS; ++i) { - if (fcntl(fd, F_SETLK, &fileLockInfo) != -1) { - fd_ = fd; - return E_OK; + if (fcntl(fd_, F_SETLK, &fileLockInfo) != -1) { + LOG_DEBUG("successfully obtained file lock"); + return; } + LOG_DEBUG("Attempt to obtain file lock again %{public}d", errno); std::this_thread::sleep_for(WAIT_CONNECT_TIMEOUT); } - close(fd); - return E_ERROR; + LOG_ERROR("attempt to lock file %{public}s failed. Please try again", ExtractFileName(path).c_str()); } -int PreferencesFileLock::UnLock() +PreferencesFileLock::~PreferencesFileLock() { - int errCode = E_OK; if (fd_ > 0) { struct flock fileLockInfo = { 0 }; fileLockInfo.l_type = F_UNLCK; @@ -77,17 +78,15 @@ int PreferencesFileLock::UnLock() fileLockInfo.l_len = 0; if (fcntl(fd_, F_SETLK, &fileLockInfo) == -1) { LOG_ERROR("failed to release file lock error %{public}d.", errno); - errCode = E_ERROR; } close(fd_); fd_ = -1; } - return errCode; } #else -PreferencesFileLock::PreferencesFileLock() +PreferencesFileLock::PreferencesFileLock(const std::string &path, const std::string &dataGroupId) { fd_ = -1; } @@ -96,15 +95,6 @@ PreferencesFileLock::~PreferencesFileLock() { } -int PreferencesFileLock::TryLock(const std::string &fileName) -{ - return E_OK; -} - -int PreferencesFileLock::UnLock() -{ - return E_OK; -} #endif } // End of namespace NativePreferences } // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/src/preferences_helper.cpp b/preferences/frameworks/native/src/preferences_helper.cpp index 0bd21078ff2ef6cd4c3977d241a09361c3126354..cc7ac85eb5fcce151263d2661e95d5242c78553f 100644 --- a/preferences/frameworks/native/src/preferences_helper.cpp +++ b/preferences/frameworks/native/src/preferences_helper.cpp @@ -23,10 +23,10 @@ #include "log_print.h" #include "preferences.h" #include "preferences_errno.h" +#include "preferences_file_lock.h" #include "preferences_file_operation.h" #include "preferences_impl.h" #include "securec.h" - namespace OHOS { namespace NativePreferences { std::map> PreferencesHelper::prefsCache_; @@ -115,8 +115,10 @@ int PreferencesHelper::DeletePreferences(const std::string &path) } std::lock_guard lock(prefsCacheMutex_); + std::string dataGroupId = ""; std::map>::iterator it = prefsCache_.find(realPath); if (it != prefsCache_.end()) { + dataGroupId = it->second->GetGroupId(); prefsCache_.erase(it); } @@ -125,10 +127,16 @@ int PreferencesHelper::DeletePreferences(const std::string &path) std::string brokenPath = PreferencesImpl::MakeFilePath(filePath, STR_BROKEN); std::string lockFilePath = PreferencesImpl::MakeFilePath(filePath, STR_LOCK); + PreferencesFileLock(lockFilePath, dataGroupId); + std::remove(filePath.c_str()); std::remove(backupPath.c_str()); std::remove(brokenPath.c_str()); + if (!dataGroupId.empty()) { + std::remove(lockFilePath.c_str()); + } + if (IsFileExist(filePath) || IsFileExist(backupPath) || IsFileExist(brokenPath)) { return E_DELETE_FILE_FAIL; } diff --git a/preferences/frameworks/native/src/preferences_impl.cpp b/preferences/frameworks/native/src/preferences_impl.cpp index abe2bc050198a4dfc9f63fefb8da98532523e92a..1739754653510351d409ccb29a67495717318b90 100644 --- a/preferences/frameworks/native/src/preferences_impl.cpp +++ b/preferences/frameworks/native/src/preferences_impl.cpp @@ -139,7 +139,7 @@ void PreferencesImpl::LoadFromDisk(std::shared_ptr pref) if (pref->loaded_) { return; } - pref->ReadSettingXml(pref->options_.filePath, pref->map_); + pref->ReadSettingXml(pref); pref->loaded_ = true; pref->cond_.notify_all(); } @@ -159,7 +159,7 @@ void PreferencesImpl::WriteToDiskFile(std::shared_ptr pref, std return; } - if (pref->WriteSettingXml(pref->options_.filePath, mcr->writeToDiskMap_)) { + if (pref->WriteSettingXml(pref, mcr->writeToDiskMap_)) { pref->diskStateGeneration_ = mcr->memoryStateGeneration_; mcr->SetDiskWriteResult(true, E_OK); } else { @@ -253,15 +253,15 @@ void ReadXmlElement(const Element &element, std::map &prefMap) +bool PreferencesImpl::ReadSettingXml(std::shared_ptr pref) { std::vector settings; - if (!PreferencesXmlUtils::ReadSettingXml(prefPath, settings)) { + if (!PreferencesXmlUtils::ReadSettingXml(pref->options_.filePath, pref->options_.dataGroupId, settings)) { return false; } for (const auto &element : settings) { - ReadXmlElement(element, prefMap); + ReadXmlElement(element, pref->map_); } return true; } @@ -313,7 +313,7 @@ void WriteXmlElement(Element &elem, const PreferencesValue &value) } bool PreferencesImpl::WriteSettingXml( - const std::string &prefPath, const std::map &prefMap) + std::shared_ptr pref, const std::map &prefMap) { std::vector settings; for (auto it = prefMap.begin(); it != prefMap.end(); it++) { @@ -324,7 +324,7 @@ bool PreferencesImpl::WriteSettingXml( settings.push_back(elem); } - return PreferencesXmlUtils::WriteSettingXml(prefPath, settings); + return PreferencesXmlUtils::WriteSettingXml(pref->options_.filePath, pref->options_.dataGroupId, settings); } bool PreferencesImpl::HasKey(const std::string &key) diff --git a/preferences/frameworks/native/src/preferences_xml_utils.cpp b/preferences/frameworks/native/src/preferences_xml_utils.cpp index 74d02e151d423cb578b02bf803dd26aa3542849f..7e4168af6fd83cd360e39ef662a6329c06cf4c6b 100644 --- a/preferences/frameworks/native/src/preferences_xml_utils.cpp +++ b/preferences/frameworks/native/src/preferences_xml_utils.cpp @@ -22,8 +22,9 @@ #include "libxml/parser.h" #include "log_print.h" +#include "preferences_file_lock.h" +#include "preferences_file_operation.h" #include "preferences_impl.h" - namespace OHOS { namespace NativePreferences { static bool ParseNodeElement(const xmlNode *node, Element &element); @@ -91,14 +92,17 @@ static xmlDoc *ReadFile(const std::string &fileName) return xmlReadFile(fileName.c_str(), "UTF-8", XML_PARSE_NOBLANKS); } -static xmlDoc *XmlReadFile(const std::string &fileName) +static xmlDoc *XmlReadFile(const std::string &fileName, const std::string &dataGroupId) { xmlDoc *doc = nullptr; + PreferencesFileLock(PreferencesImpl::MakeFilePath(fileName, STR_LOCK), dataGroupId); if (IsFileExist(fileName)) { doc = ReadFile(fileName); if (doc != nullptr) { return doc; } + xmlErrorPtr xmlErr = xmlGetLastError(); + LOG_ERROR("failed to read XML format file, error is %{public}s.", xmlErr->message); if (!RenameToBrokenFile(fileName)) { return doc; } @@ -110,14 +114,15 @@ static xmlDoc *XmlReadFile(const std::string &fileName) } /* static */ -bool PreferencesXmlUtils::ReadSettingXml(const std::string &fileName, std::vector &settings) +bool PreferencesXmlUtils::ReadSettingXml( + const std::string &fileName, const std::string &dataGroupId, std::vector &settings) { LOG_RECORD_FILE_NAME("Read setting xml start."); if (fileName.size() == 0) { LOG_ERROR("The length of the file name is 0."); return false; } - auto doc = std::shared_ptr(XmlReadFile(fileName), [](xmlDoc *doc) { xmlFreeDoc(doc); }); + auto doc = std::shared_ptr(XmlReadFile(fileName, dataGroupId), [](xmlDoc *doc) { xmlFreeDoc(doc); }); if (doc == nullptr) { return false; } @@ -266,14 +271,16 @@ static bool SaveFormatFileEnc(const std::string &fileName, xmlDoc *doc) return xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1) > 0; } -bool XmlSaveFormatFileEnc(const std::string &fileName, xmlDoc *doc) +bool XmlSaveFormatFileEnc(const std::string &fileName, const std::string &dataGroupId, xmlDoc *doc) { + PreferencesFileLock(PreferencesImpl::MakeFilePath(fileName, STR_LOCK), dataGroupId); if (IsFileExist(fileName) && !RenameToBackupFile(fileName)) { return false; } if (!SaveFormatFileEnc(fileName, doc)) { - LOG_ERROR("Failed to save XML format file, attempting to restore backup"); + xmlErrorPtr xmlErr = xmlGetLastError(); + LOG_ERROR("failed to save XML format file, error is %{public}s.", xmlErr->message); if (IsFileExist(fileName)) { RenameToBrokenFile(fileName); } @@ -283,12 +290,17 @@ bool XmlSaveFormatFileEnc(const std::string &fileName, xmlDoc *doc) RemoveBackupFile(fileName); PreferencesXmlUtils::LimitXmlPermission(fileName); + // make sure the file is written to disk. + if (!Fsync(fileName)) { + LOG_WARN("failed to write the file to the disk."); + } LOG_DEBUG("successfully saved the XML format file"); return true; } /* static */ -bool PreferencesXmlUtils::WriteSettingXml(const std::string &fileName, std::vector &settings) +bool PreferencesXmlUtils::WriteSettingXml( + const std::string &fileName, const std::string &dataGroupId, const std::vector &settings) { LOG_RECORD_FILE_NAME("Write setting xml start."); if (fileName.size() == 0) { @@ -328,7 +340,7 @@ bool PreferencesXmlUtils::WriteSettingXml(const std::string &fileName, std::vect } /* 1: formatting spaces are added. */ - bool result = XmlSaveFormatFileEnc(fileName.c_str(), doc.get()); + bool result = XmlSaveFormatFileEnc(fileName, dataGroupId, doc.get()); LOG_RECORD_FILE_NAME("Write setting xml end."); return result; } diff --git a/preferences/interfaces/inner_api/include/preferences.h b/preferences/interfaces/inner_api/include/preferences.h index ef4b55edd7a827e46d8876a60150a488926598e0..2a34fd081d5f4de05dd9b8882c1c7b71992aa990 100644 --- a/preferences/interfaces/inner_api/include/preferences.h +++ b/preferences/interfaces/inner_api/include/preferences.h @@ -312,6 +312,18 @@ public: */ virtual int UnRegisterObserver( std::shared_ptr preferencesObserver, RegisterMode mode = RegisterMode::LOCAL_CHANGE) = 0; + + /** + * @brief Get group id. + * + * This function is used to Get group id. + * + * @return Returns the groupId when it exists, otherwise returns an empty string. + */ + virtual std::string GetGroupId() const + { + return ""; + } }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js index 6a637ec5b4379df8e9c3a2a0e33c9b135b88763e..175e25edb13d21e46b3f3782dd8873ee889a0542 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js @@ -31,17 +31,25 @@ var context; const TAG = '[PREFERENCES_CALLBACK_JSUNIT_TEST]' describe('PreferencesCallBackJsunit', function () { - beforeAll(async function () { + beforeAll(function () { console.info('beforeAll') context = featureAbility.getContext() + }) + + beforeEach(async function () { + console.info('beforeEach'); mPreferences = await data_preferences.getPreferences(context, NAME); }) - afterAll(async function () { - console.info('afterAll') + afterEach(async function () { + console.info('afterEach'); await data_preferences.deletePreferences(context, NAME); }) + afterAll(function () { + console.info('afterAll') + }) + /** * @tc.name clear callback interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0010 @@ -50,7 +58,7 @@ describe('PreferencesCallBackJsunit', function () { it('testPreferencesClear0012', 0, async function (done) { await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); await mPreferences.flush(); - await mPreferences.clear(async function (err, ret) { + mPreferences.clear(async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue") expect("defaultvalue").assertEqual(pre); done(); @@ -64,7 +72,7 @@ describe('PreferencesCallBackJsunit', function () { */ it('testPreferencesHasKey0032', 0, async function (done) { await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); - await mPreferences.has(KEY_TEST_STRING_ELEMENT, function (err, ret) { + mPreferences.has(KEY_TEST_STRING_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -77,7 +85,7 @@ describe('PreferencesCallBackJsunit', function () { */ it('testPreferencesHasKey0033', 0, async function (done) { await mPreferences.put(KEY_TEST_INT_ELEMENT, 1); - await mPreferences.has(KEY_TEST_INT_ELEMENT, function (err, ret) { + mPreferences.has(KEY_TEST_INT_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -90,7 +98,7 @@ describe('PreferencesCallBackJsunit', function () { */ it('testPreferencesHasKey0034', 0, async function (done) { await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 1.1); - await mPreferences.has(KEY_TEST_FLOAT_ELEMENT, function (err, ret) { + mPreferences.has(KEY_TEST_FLOAT_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -103,7 +111,7 @@ describe('PreferencesCallBackJsunit', function () { */ it('testPreferencesHasKey0035', 0, async function (done) { await mPreferences.put(KEY_TEST_LONG_ELEMENT, 0); - await mPreferences.has(KEY_TEST_LONG_ELEMENT, function (err, ret) { + mPreferences.has(KEY_TEST_LONG_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -116,7 +124,7 @@ describe('PreferencesCallBackJsunit', function () { */ it('testPreferencesHasKey0036', 0, async function (done) { await mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, false); - await mPreferences.has(KEY_TEST_BOOLEAN_ELEMENT, function (err, ret) { + mPreferences.has(KEY_TEST_BOOLEAN_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -128,8 +136,7 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc get defaultValue callback interface test */ it('testPreferencesGetDefValue0062', 0, async function (done) { - await mPreferences.clear(); - await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultValue", function (err, ret) { + mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultValue", function (err, ret) { expect('defaultValue').assertEqual(ret); done(); }) @@ -141,9 +148,8 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc get float callback interface test */ it('testPreferencesGetFloat0072', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 3.0); - await mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0, function (err, ret) { + mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0, function (err, ret) { expect(3.0).assertEqual(ret); done(); }) @@ -155,9 +161,8 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc get int callback interface test */ it('testPreferencesGetInt0082', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_INT_ELEMENT, 3); - await mPreferences.get(KEY_TEST_INT_ELEMENT, 0.0, function (err, ret) { + mPreferences.get(KEY_TEST_INT_ELEMENT, 0.0, function (err, ret) { expect(3).assertEqual(ret); done(); }) @@ -169,11 +174,10 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc get long callback interface test */ it('testPreferencesGetLong0092', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_LONG_ELEMENT, 3); let pref = await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0) expect(3).assertEqual(pref); - await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0, function (err, ret) { + mPreferences.get(KEY_TEST_LONG_ELEMENT, 0, function (err, ret) { expect(3).assertEqual(ret); done(); }); @@ -185,10 +189,8 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc get String callback interface test */ it('testPreferencesGetString102', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); - await mPreferences.flush(); - await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue", function (err, ret) { + mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue", function (err, ret) { expect('test').assertEqual(ret); done(); }); @@ -200,14 +202,16 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put boolean callback interface test */ it('testPreferencesPutBoolean0122', 0, async function (done) { - await mPreferences.clear(); - await mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, true, async function (err, ret) { + mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, true, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_BOOLEAN_ELEMENT, false); expect(true).assertEqual(pre); await mPreferences.flush(); - let pre2 = await mPreferences.get(KEY_TEST_BOOLEAN_ELEMENT, false) - expect(true).assertEqual(pre2); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); + let pre2 = await mPreferences.get(KEY_TEST_BOOLEAN_ELEMENT, false); done(); + expect(true).assertEqual(pre2); }); }) @@ -217,14 +221,16 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put float callback interface test */ it('testPreferencesPutFloat0132', 0, async function (done) { - await mPreferences.clear(); - await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 4.0, async function (err, ret) { + mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 4.0, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0); expect(4.0).assertEqual(pre); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0); - expect(4.0).assertEqual(pre2); done(); + expect(4.0).assertEqual(pre2); }); }) @@ -234,14 +240,16 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put int callback interface test */ it('testPreferencesPutInt0142', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_INT_ELEMENT, 4, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_INT_ELEMENT, 0); expect(4).assertEqual(pre); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_INT_ELEMENT, 0); - expect(4).assertEqual(pre2); done(); + expect(4).assertEqual(pre2); }); }) @@ -251,15 +259,17 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put long callback interface test */ it('testPreferencesPutLong0152', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_LONG_ELEMENT, 4); await mPreferences.put(KEY_TEST_LONG_ELEMENT, 4, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0); expect(4).assertEqual(pre); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0); - expect(4).assertEqual(pre2); done(); + expect(4).assertEqual(pre2); }); }) @@ -269,14 +279,16 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put String callback interface test */ it('testPreferencesPutString0162', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_STRING_ELEMENT, '', async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue") expect('').assertEqual(pre); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue") - expect('').assertEqual(pre2); done(); + expect('').assertEqual(pre2); }); }) @@ -324,14 +336,12 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put String callback interface test */ it('testPreferencesPutStringArray0001', 0, async function (done) { - await mPreferences.clear(); var stringArr = ['11', '22', '33'] - await mPreferences.put(KEY_TEST_STRING_ARRAY_ELEMENT, stringArr, async function (err, ret) { + mPreferences.put(KEY_TEST_STRING_ARRAY_ELEMENT, stringArr, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_STRING_ARRAY_ELEMENT, ['123', '321']) for (let i = 0; i < stringArr.length; i++) { expect(stringArr[i]).assertEqual(pre[i]); } - done(); }); }) @@ -342,14 +352,12 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put String callback interface test */ it('testPreferencesPutNumArray0001', 0, async function (done) { - await mPreferences.clear(); var doubleArr = [11, 22, 33] - await mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, doubleArr, async function (err, ret) { + mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, doubleArr, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, [123, 321]) for (let i = 0; i < doubleArr.length; i++) { expect(doubleArr[i]).assertEqual(pre[i]); } - done(); }); }) @@ -360,14 +368,12 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put String callback interface test */ it('testPreferencesPutBoolArray0001', 0, async function (done) { - await mPreferences.clear(); let boolArr = [true, false, false, true] await mPreferences.put(KEY_TEST_BOOL_ARRAY_ELEMENT, boolArr, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_BOOL_ARRAY_ELEMENT, [true, false]) for (let i = 0; i < boolArr.length; i++) { expect(boolArr[i]).assertEqual(pre[i]); } - done(); }); }) @@ -378,7 +384,6 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc getAll callback interface test */ it('testPreferencesGetAll0001', 0, async function (done) { - await mPreferences.clear(); let doubleArr = [11, 22, 33] let stringArr = ['11', '22', '33'] let boolArr = [true, false, false, true] @@ -388,9 +393,6 @@ describe('PreferencesCallBackJsunit', function () { await mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, false) await mPreferences.put(KEY_TEST_STRING_ELEMENT, "123") await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 123.1) - - await mPreferences.flush() - await mPreferences.getAll(function (err, obj) { expect(false).assertEqual(obj.key_test_boolean) expect("123").assertEqual(obj.key_test_string) @@ -399,17 +401,14 @@ describe('PreferencesCallBackJsunit', function () { for (let i = 0; i < sArr.length; i++) { expect(sArr[i]).assertEqual(stringArr[i]); } - let bArr = obj.key_test_bool_array for (let i = 0; i < bArr.length; i++) { expect(bArr[i]).assertEqual(boolArr[i]); } - let nArr = obj.key_test_number_array for (let i = 0; i < nArr.length; i++) { expect(nArr[i]).assertEqual(doubleArr[i]); } - done() }) }) @@ -437,7 +436,6 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc flush empty array callback interface test */ it('testPreferencesFlushEmptyArray0001', 0, async function (done) { - await mPreferences.clear(); let value = new Array(); await mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, value, async function(err, ret) { if (err) { @@ -448,6 +446,9 @@ describe('PreferencesCallBackJsunit', function () { expect(pre instanceof Array).assertEqual(true); expect(pre.length).assertEqual(0); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue") expect(pre2 instanceof Array).assertEqual(true); expect(pre2.length).assertEqual(0); @@ -461,7 +462,6 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc flush empty array callback interface test */ it('testPreferencesFlushEmptyArray0002', 0, async function (done) { - await mPreferences.clear(); await mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, [], async function(err, ret) { if (err) { expect(null).assertFail(); @@ -471,6 +471,9 @@ describe('PreferencesCallBackJsunit', function () { expect(pre instanceof Array).assertEqual(true); expect(pre.length).assertEqual(0); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue") expect(pre2 instanceof Array).assertEqual(true); expect(pre2.length).assertEqual(0); diff --git a/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js index 0d92d226aeb6b7a7e64fdbd1a17e63d5ca2e3dea..9ca63129c97dad99f5324943edea0ac1f8e87066 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js @@ -22,26 +22,32 @@ const KEY_TEST_STRING_ELEMENT = 'key_test_string'; var mPreferences; var context; describe('PreferencesHelperJsunit', function () { - beforeAll(async function () { - console.info('beforeAll') - context = featureAbility.getContext() + beforeAll(function () { + console.info('beforeAll'); + context = featureAbility.getContext(); + }) + + beforeEach(async function () { + console.info('beforeEach'); mPreferences = await data_preferences.getPreferences(context, NAME); }) - afterAll(async function () { - console.info('afterAll') + afterEach(async function () { + console.info('afterEach'); await data_preferences.deletePreferences(context, NAME); }) + afterAll(function () { + console.info('afterAll') + }) + /** * @tc.name getPreferences interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_001 * @tc.desc getPreferences interface test */ it('testGetPreferencesHelper001', 0, async function () { - mPreferences = await data_preferences.getPreferences(context, NAME); await mPreferences.put('test', 2); - await mPreferences.flush(); var value = await mPreferences.get('test', 0); expect(value).assertEqual(2); }) @@ -53,16 +59,14 @@ describe('PreferencesHelperJsunit', function () { */ it('testGetPreferencesHelper002', 0, async function (done) { const promise = data_preferences.getPreferences(context, NAME); - promise.then(async (pref) => { + await promise.then(async (pref) => { await pref.put('test', 2); - await pref.flush(); var value = await mPreferences.get('test', 0); done(); expect(value).assertEqual(2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -144,16 +148,14 @@ describe('PreferencesHelperJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_removePreferencesFromCache_001 * @tc.desc removePreferencesFromCache interface test */ - it('testRemovePreferencesFromCache001', 0, async function (done) { + it('testRemovePreferencesFromCache001', 0, async function () { let perf = await data_preferences.getPreferences(context, NAME); perf = null; const promise = data_preferences.removePreferencesFromCache(context, NAME); - promise.then((pref) => { + await promise.then((pref) => { }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -191,16 +193,14 @@ describe('PreferencesHelperJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_deletePreferences_001 * @tc.desc deletePreferences interface test */ - it('testDeletePreferencesHelper001', 0, async function (done) { + it('testDeletePreferencesHelper001', 0, async function () { let perf = await data_preferences.getPreferences(context, NAME); perf = null; const promise = data_preferences.deletePreferences(context, NAME); - promise.then((pref) => { + await promise.then((pref) => { }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** diff --git a/preferences/test/js/unittest/preferences/src/PreferencesHelperSyncJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesHelperSyncJsunit.test.js index 28cf90849994d015620a23c856f135e29813c52a..3110373d5835577847978f3714f79147eaea3a75 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesHelperSyncJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesHelperSyncJsunit.test.js @@ -22,8 +22,8 @@ var context; describe('preferencesSyncTest', function () { beforeAll(async function () { - console.info('beforeAll') - context = featureAbility.getContext() + console.info('beforeAll'); + context = featureAbility.getContext(); }) afterAll(async function () { @@ -41,6 +41,7 @@ describe('preferencesSyncTest', function () { expect(preferences.hasSync(KEY_TEST_STRING_ELEMENT)).assertTrue(); let val = preferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect("132").assertEqual(val); + data_preferences.deletePreferencesSync(context, { name: NAME }); }) /** @@ -55,11 +56,10 @@ describe('preferencesSyncTest', function () { let val = preferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect("132").assertEqual(val); preferences = null; - data_preferences.removePreferencesFromCacheSync(context, NAME); - let preferences1 = data_preferences.getPreferencesSync(context, NAME); expect(preferences1.hasSync(KEY_TEST_STRING_ELEMENT)).assertFalse(); + data_preferences.deletePreferencesSync(context, NAME); }) /** @@ -74,10 +74,9 @@ describe('preferencesSyncTest', function () { let val = preferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect("132").assertEqual(val); preferences = null; - data_preferences.removePreferencesFromCacheSync(context, { name: NAME }); - let preferences1 = data_preferences.getPreferencesSync(context, { name: NAME }); expect(preferences1.hasSync(KEY_TEST_STRING_ELEMENT)).assertFalse(); + data_preferences.deletePreferencesSync(context, { name: NAME }); }) }) \ No newline at end of file diff --git a/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js index 51cbca3bc05bee567ec0b7217755420f75deb1f0..7985a3702ddb5e4b2558e8d4a2ad26af0225f770 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js @@ -29,39 +29,37 @@ var mPreferences; var context; describe('PreferencesPromiseJsunit', function () { - beforeAll(async function () { - console.info('beforeAll') - context = featureAbility.getContext() + beforeAll(function () { + console.info('beforeAll'); + context = featureAbility.getContext(); + }) + + beforeEach(async function () { + console.info('beforeEach'); mPreferences = await data_preferences.getPreferences(context, NAME); }) - afterAll(async function () { - console.info('afterAll') + afterEach(async function () { + console.info('afterEach'); await data_preferences.deletePreferences(context, NAME); }) + afterAll(function () { + console.info('afterAll') + }) + /** * @tc.name put StringArray promise interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0131 * @tc.desc put StringArray promise interface test */ - it('testPreferencesPutStringArray0131', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesPutStringArray0131', 0, async function () { var stringArr = ['1', '2', '3'] - let promise1 = mPreferences.put(KEY_TEST_STRING_ARRAY_ELEMENT, stringArr) - await promise1 - let promise2 = mPreferences.get(KEY_TEST_STRING_ARRAY_ELEMENT, ['123', '321']) - promise2.then((pre) => { - for (let i = 0; i < stringArr.length; i++) { - expect(stringArr[i]).assertEqual(pre[i]); - } - - }).catch((err) => { - expect(null).assertFail(); - }) - await promise2 - - done(); + await mPreferences.put(KEY_TEST_STRING_ARRAY_ELEMENT, stringArr); + let pre = await mPreferences.get(KEY_TEST_STRING_ARRAY_ELEMENT, ['123', '321']); + for (let i = 0; i < stringArr.length; i++) { + expect(stringArr[i]).assertEqual(pre[i]); + } }); /** @@ -69,22 +67,13 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0132 * @tc.desc put NumberArray promise interface test */ - it('testPreferencesPutNumberArray0132', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesPutNumberArray0132', 0, async function () { var numberArr = [11, 22, 33, 44, 55] - let promise1 = mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, numberArr) - await promise1 - let promise2 = mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, [123, 321]) - promise2.then((pre) => { - for (let i = 0; i < numberArr.length; i++) { - expect(numberArr[i]).assertEqual(pre[i]); - } - }).catch((err) => { - expect(null).assertFail(); - }) - await promise2 - - done(); + await mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, numberArr); + let pre = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, [123, 321]); + for (let i = 0; i < numberArr.length; i++) { + expect(numberArr[i]).assertEqual(pre[i]); + } }); /** @@ -92,22 +81,13 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0133 * @tc.desc put BoolArray promise interface test */ - it('testPreferencesPutBoolArray0133', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesPutBoolArray0133', 0, async function () { var boolArr = [true, true, false] - let promise1 = mPreferences.put(KEY_TEST_BOOL_ARRAY_ELEMENT, boolArr) - await promise1 - let promise2 = mPreferences.get(KEY_TEST_BOOL_ARRAY_ELEMENT, [false, true]) - promise2.then((pre) => { - for (let i = 0; i < boolArr.length; i++) { - expect(boolArr[i]).assertEqual(pre[i]); - } - }).catch((err) => { - expect(null).assertFail(); - }) - await promise2 - - done(); + await mPreferences.put(KEY_TEST_BOOL_ARRAY_ELEMENT, boolArr); + let pre = await mPreferences.get(KEY_TEST_BOOL_ARRAY_ELEMENT, [false, true]); + for (let i = 0; i < boolArr.length; i++) { + expect(boolArr[i]).assertEqual(pre[i]); + } }); /** @@ -115,8 +95,7 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0133 * @tc.desc getAll promise interface test */ - it('testPreferencesGetAll0001', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesGetAll0001', 0, async function () { let doubleArr = [11, 22, 33] let stringArr = ['11', '22', '33'] let boolArr = [true, false, false, true] @@ -126,11 +105,8 @@ describe('PreferencesPromiseJsunit', function () { await mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, false) await mPreferences.put(KEY_TEST_STRING_ELEMENT, "123") await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 123.1) - - await mPreferences.flush() - let promise = mPreferences.getAll() - promise.then((obj) => { + await promise.then((obj) => { expect(false).assertEqual(obj.key_test_boolean) expect("123").assertEqual(obj.key_test_string) expect(123.1).assertEqual(obj.key_test_float) @@ -138,12 +114,10 @@ describe('PreferencesPromiseJsunit', function () { for (let i = 0; i < sArr.length; i++) { expect(sArr[i]).assertEqual(stringArr[i]); } - let bArr = obj.key_test_bool_array for (let i = 0; i < bArr.length; i++) { expect(bArr[i]).assertEqual(boolArr[i]); } - let nArr = obj.key_test_number_array for (let i = 0; i < nArr.length; i++) { expect(nArr[i]).assertEqual(doubleArr[i]); @@ -151,9 +125,6 @@ describe('PreferencesPromiseJsunit', function () { }).catch((err) => { expect(null).assertFail(); }) - await promise - - done(); }) /** @@ -165,14 +136,13 @@ describe('PreferencesPromiseJsunit', function () { await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); await mPreferences.flush(); const promise = mPreferences.clear(); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue"); done(); expect("defaultvalue").assertEqual(per); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -180,16 +150,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0020 * @tc.desc has string interface test */ - it('testPreferencesHasKey0031', 0, async function (done) { + it('testPreferencesHasKey0031', 0, async function () { await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); const promise = mPreferences.has(KEY_TEST_STRING_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -197,16 +165,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0140 * @tc.desc has int interface test */ - it('testPreferencesHasKey0032', 0, async function (done) { + it('testPreferencesHasKey0032', 0, async function () { await mPreferences.put(KEY_TEST_INT_ELEMENT, 1); const promise = mPreferences.has(KEY_TEST_INT_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -214,16 +180,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0150 * @tc.desc has float interface test */ - it('testPreferencesHasKey0033', 0, async function (done) { + it('testPreferencesHasKey0033', 0, async function () { await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 2.0); const promise = mPreferences.has(KEY_TEST_FLOAT_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); - }); - await promise; - done(); + }); }) /** @@ -231,16 +195,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0160 * @tc.desc has boolean interface test */ - it('testPreferencesHasKey0034', 0, async function (done) { + it('testPreferencesHasKey0034', 0, async function () { await mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, false); const promise = mPreferences.has(KEY_TEST_BOOLEAN_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -248,16 +210,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0170 * @tc.desc has long interface test */ - it('testPreferencesHasKey0035', 0, async function (done) { + it('testPreferencesHasKey0035', 0, async function () { await mPreferences.put(KEY_TEST_LONG_ELEMENT, 0); const promise = mPreferences.has(KEY_TEST_LONG_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -265,16 +225,13 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0030 * @tc.desc get string promise interface test */ - it('testPreferencesGetDefValue0061', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesGetDefValue0061', 0, async function () { const promise = mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultValue"); - promise.then((ret) => { + await promise.then((ret) => { expect('defaultValue').assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -282,17 +239,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0040 * @tc.desc get float promise interface test */ - it('testPreferencesGetFloat0071', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesGetFloat0071', 0, async function () { await mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 3.0); const promise = mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0); - promise.then((ret) => { + await promise.then((ret) => { expect(3.0).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -300,17 +254,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0050 * @tc.desc get int promise interface test */ - it('testPreferencesGetInt0081', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesGetInt0081', 0, async function () { await mPreferences.put(KEY_TEST_INT_ELEMENT, 3); const promise = mPreferences.get(KEY_TEST_INT_ELEMENT, 0.0); - promise.then((ret) => { + await promise.then((ret) => { expect(3).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -318,17 +269,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0060 * @tc.desc get long promise interface test */ - it('testPreferencesGetLong0091', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesGetLong0091', 0, async function () { await mPreferences.put(KEY_TEST_LONG_ELEMENT, 3); const promise = mPreferences.get(KEY_TEST_LONG_ELEMENT, 0); - promise.then((ret) => { + await promise.then((ret) => { expect(3).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -336,18 +284,14 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0070 * @tc.desc get String promise interface test */ - it('tesPreferencesGetString101', 0, async function (done) { - await mPreferences.clear(); + it('tesPreferencesGetString101', 0, async function () { await mPreferences.put(KEY_TEST_STRING_ELEMENT, "test"); - await mPreferences.flush(); const promise = mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue"); - promise.then((ret) => { + await promise.then((ret) => { expect('test').assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -357,17 +301,19 @@ describe('PreferencesPromiseJsunit', function () { */ it('testPreferencesPutBoolean0121', 0, async function (done) { const promise = mPreferences.put(KEY_TEST_BOOLEAN_ELEMENT, true); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_BOOLEAN_ELEMENT, false); expect(true).assertEqual(per); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let per2 = await mPreferences.get(KEY_TEST_BOOLEAN_ELEMENT, false); done(); expect(true).assertEqual(per2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -377,17 +323,19 @@ describe('PreferencesPromiseJsunit', function () { */ it('testPreferencesPutFloat0131', 0, async function (done) { const promise = mPreferences.put(KEY_TEST_FLOAT_ELEMENT, 4.0); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0); expect(4.0).assertEqual(per); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let per2 = await mPreferences.get(KEY_TEST_FLOAT_ELEMENT, 0.0); done(); expect(4.0).assertEqual(per2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -395,19 +343,20 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0110 * @tc.desc put int promise interface test */ - it('testPreferencesPutInt0141', 0, async function (done) { + it('testPreferencesPutInt0141', 0, async function () { const promise = mPreferences.put(KEY_TEST_INT_ELEMENT, 4); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_INT_ELEMENT, 0); expect(4).assertEqual(per); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let per2 = await mPreferences.get(KEY_TEST_INT_ELEMENT, 0); - done(); expect(4).assertEqual(per2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -415,19 +364,20 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0120 * @tc.desc put long promise interface test */ - it('testPreferencesPutLong0151', 0, async function (done) { + it('testPreferencesPutLong0151', 0, async function () { const promise = mPreferences.put(KEY_TEST_LONG_ELEMENT, 4); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0); expect(4).assertEqual(per); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let per2 = await mPreferences.get(KEY_TEST_LONG_ELEMENT, 0); - done(); expect(4).assertEqual(per2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -437,17 +387,19 @@ describe('PreferencesPromiseJsunit', function () { */ it('testPreferencesPutString0161', 0, async function (done) { const promise = mPreferences.put(KEY_TEST_STRING_ELEMENT, ''); - promise.then(async (ret) => { + await promise.then(async (ret) => { let per = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue") expect('').assertEqual(per); await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let per2 = await mPreferences.get(KEY_TEST_STRING_ELEMENT, "defaultvalue") done(); expect('').assertEqual(per2); }).catch((err) => { expect(null).assertFail(); }); - await promise; }) /** @@ -472,24 +424,23 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0132 * @tc.desc get empty array promise interface test */ - it('testPreferencesFlushEmptyArray0181', 0, async function (done) { - await mPreferences.clear(); + it('testPreferencesFlushEmptyArray0181', 0, async function () { let value = new Array(); const promise = mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, value); - promise.then(async (ret) => { + await promise.then(async (ret) => { let pre = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue"); expect(pre instanceof Array).assertEqual(true); expect(pre.length).assertEqual(0); - await mPreferences.flush(); + await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue") expect(pre2 instanceof Array).assertEqual(true); expect(pre2.length).assertEqual(0); - done(); }).catch((err) => { expect(null).assertFail(); - done(); }); - await promise; }) /** @@ -497,22 +448,21 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0132 * @tc.desc get empty array promise interface test */ - it('testPreferencesGetEmptyArray0191', 0, async function (done) { - await mPreferences.clear(); - const promise = mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, []); - promise.then(async (ret) => { - let pre = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue"); - expect(pre instanceof Array).assertEqual(true); - expect(pre.length).assertEqual(0); - await mPreferences.flush(); - let pre2 = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue") - expect(pre2 instanceof Array).assertEqual(true); - expect(pre2.length).assertEqual(0); - done(); - }).catch((err) => { - expect(null).assertFail(); - done(); - }); - await promise; - }) + it('testPreferencesGetEmptyArray0191', 0, async function () { + const promise = mPreferences.put(KEY_TEST_NUMBER_ARRAY_ELEMENT, []); + await promise.then(async (ret) => { + let pre = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue"); + expect(pre instanceof Array).assertEqual(true); + expect(pre.length).assertEqual(0); + await mPreferences.flush(); + await data_preferences.removePreferencesFromCache(context, NAME); + mPreferences = null; + mPreferences = await data_preferences.getPreferences(context, NAME); + let pre2 = await mPreferences.get(KEY_TEST_NUMBER_ARRAY_ELEMENT, "defaultvalue") + expect(pre2 instanceof Array).assertEqual(true); + expect(pre2.length).assertEqual(0); + }).catch((err) => { + expect(null).assertFail(); + }); + }) }) \ No newline at end of file diff --git a/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js index 65eb928f9d63b5039c4196ca242b715affae8e5f..bd6b9db9d38188642cb3b731881061b6f51b71a1 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js @@ -29,31 +29,37 @@ var mPreferences; var context; describe('preferencesSyncTest', function () { - beforeAll(async function () { - console.info('beforeAll') - context = featureAbility.getContext() - mPreferences = await data_preferences.getPreferences(context, NAME); + beforeAll(function () { + console.info('beforeAll'); + context = featureAbility.getContext(); }) - afterAll(async function () { - console.info('afterAll') + beforeEach(async function () { + console.info('beforeEach'); + mPreferences = await data_preferences.getPreferencesSync(context, NAME); + }) + + afterEach(async function () { + console.info('afterEach'); await data_preferences.deletePreferences(context, NAME); }) + afterAll(function () { + console.info('afterAll') + }) + /** * @tc.name put StringArray promise interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0131 * @tc.desc put StringArray promise interface test */ - it('testPreferencesPutStringArray0131', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutStringArray0131', 0, function () { const stringArr = ['1', '2', '3']; mPreferences.putSync(KEY_TEST_STRING_ARRAY_ELEMENT, stringArr); let rc = mPreferences.getSync(KEY_TEST_STRING_ARRAY_ELEMENT, ['123', '321']); for (let i = 0; i < stringArr.length; i++) { expect(stringArr[i]).assertEqual(rc[i]); } - done(); }); /** @@ -61,15 +67,13 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0132 * @tc.desc put NumberArray promise interface test */ - it('testPreferencesPutNumberArray0132', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutNumberArray0132', 0, function () { const numberArr = [11, 22, 33, 44, 55]; mPreferences.putSync(KEY_TEST_NUMBER_ARRAY_ELEMENT, numberArr); let rc = mPreferences.getSync(KEY_TEST_NUMBER_ARRAY_ELEMENT, [123, 321]); for (let i = 0; i < numberArr.length; i++) { expect(numberArr[i]).assertEqual(rc[i]); } - done(); }); /** @@ -77,15 +81,13 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0133 * @tc.desc put BoolArray promise interface test */ - it('testPreferencesPutBoolArray0133', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutBoolArray0133', 0, function () { const boolArr = [true, true, false]; mPreferences.putSync(KEY_TEST_BOOL_ARRAY_ELEMENT, boolArr); let rc = mPreferences.getSync(KEY_TEST_BOOL_ARRAY_ELEMENT, [false, true]); for (let i = 0; i < boolArr.length; i++) { expect(boolArr[i]).assertEqual(rc[i]); } - done(); }); /** @@ -93,8 +95,7 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0133 * @tc.desc getAll promise interface test */ - it('testPreferencesGetAll0001', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesGetAll0001', 0, function () { const doubleArr = [11, 22, 33]; const stringArr = ['11', '22', '33']; const boolArr = [true, false, false, true]; @@ -104,9 +105,6 @@ describe('preferencesSyncTest', function () { mPreferences.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); mPreferences.putSync(KEY_TEST_STRING_ELEMENT, "123"); mPreferences.putSync(KEY_TEST_FLOAT_ELEMENT, 123.1); - - await mPreferences.flush(); - let obj = mPreferences.getAllSync(); expect(false).assertEqual(obj.key_test_boolean) expect("123").assertEqual(obj.key_test_string) @@ -115,17 +113,14 @@ describe('preferencesSyncTest', function () { for (let i = 0; i < sArr.length; i++) { expect(sArr[i]).assertEqual(stringArr[i]); } - let bArr = obj.key_test_bool_array for (let i = 0; i < bArr.length; i++) { expect(bArr[i]).assertEqual(boolArr[i]); } - let nArr = obj.key_test_number_array for (let i = 0; i < nArr.length; i++) { expect(nArr[i]).assertEqual(doubleArr[i]); } - done(); }) /** @@ -133,14 +128,12 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Promise_0010 * @tc.desc clear promise interface test */ - it('testPreferencesClear0011', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesClear0011', 0, function () { mPreferences.putSync(KEY_TEST_STRING_ELEMENT, "test"); - await mPreferences.flush(); + mPreferences.flush(); mPreferences.clearSync(); let per = mPreferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect("defaultvalue").assertEqual(per); - done(); }) /** @@ -148,12 +141,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0020 * @tc.desc has string interface test */ - it('testPreferencesHasKey0031', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesHasKey0031', 0, function () { mPreferences.putSync(KEY_TEST_STRING_ELEMENT, "test"); const ret = mPreferences.hasSync(KEY_TEST_STRING_ELEMENT); expect(true).assertEqual(ret); - done(); }) /** @@ -161,12 +152,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0140 * @tc.desc has int interface test */ - it('testPreferencesHasKey0032', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesHasKey0032', 0, function () { mPreferences.putSync(KEY_TEST_INT_ELEMENT, 1); const ret = mPreferences.hasSync(KEY_TEST_INT_ELEMENT); expect(true).assertEqual(ret); - done(); }) /** @@ -174,12 +163,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0150 * @tc.desc has float interface test */ - it('testPreferencesHasKey0033', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesHasKey0033', 0, function () { mPreferences.putSync(KEY_TEST_FLOAT_ELEMENT, 2.0); const ret = mPreferences.hasSync(KEY_TEST_FLOAT_ELEMENT); expect(true).assertEqual(ret); - done(); }) /** @@ -187,12 +174,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0160 * @tc.desc has boolean interface test */ - it('testPreferencesHasKey0034', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesHasKey0034', 0, function () { mPreferences.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); const ret = mPreferences.hasSync(KEY_TEST_BOOLEAN_ELEMENT); expect(true).assertEqual(ret); - done(); }) /** @@ -200,12 +185,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0170 * @tc.desc has long interface test */ - it('testPreferencesHasKey0035', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesHasKey0035', 0, function () { mPreferences.putSync(KEY_TEST_LONG_ELEMENT, 0); const ret = mPreferences.hasSync(KEY_TEST_LONG_ELEMENT); expect(true).assertEqual(ret); - done(); }) /** @@ -213,11 +196,9 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0030 * @tc.desc get string promise interface test */ - it('testPreferencesGetDefValue0061', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesGetDefValue0061', 0, function () { const ret = mPreferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultValue"); expect('defaultValue').assertEqual(ret); - done(); }) /** @@ -225,12 +206,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0040 * @tc.desc get float promise interface test */ - it('testPreferencesGetFloat0071', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesGetFloat0071', 0, function () { mPreferences.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); const ret = mPreferences.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0); expect(3.0).assertEqual(ret); - done(); }) /** @@ -238,12 +217,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0050 * @tc.desc get int promise interface test */ - it('testPreferencesGetInt0081', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesGetInt0081', 0, function () { mPreferences.putSync(KEY_TEST_INT_ELEMENT, 3); const ret = mPreferences.getSync(KEY_TEST_INT_ELEMENT, 0.0); expect(3).assertEqual(ret); - done(); }) /** @@ -251,12 +228,10 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0060 * @tc.desc get long promise interface test */ - it('testPreferencesGetLong0091', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesGetLong0091', 0, function () { mPreferences.putSync(KEY_TEST_LONG_ELEMENT, 3); const ret = mPreferences.getSync(KEY_TEST_LONG_ELEMENT, 0); expect(3).assertEqual(ret); - done(); }) /** @@ -264,13 +239,11 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0070 * @tc.desc get String promise interface test */ - it('tesPreferencesGetString101', 0, async function (done) { - mPreferences.clearSync(); + it('tesPreferencesGetString101', 0, async function () { mPreferences.putSync(KEY_TEST_STRING_ELEMENT, "test"); await mPreferences.flush(); const ret = mPreferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect('test').assertEqual(ret); - done(); }) /** @@ -278,15 +251,16 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0090 * @tc.desc put boolean promise interface test */ - it('testPreferencesPutBoolean0121', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutBoolean0121', 0, async function () { mPreferences.putSync(KEY_TEST_BOOLEAN_ELEMENT, true); let per = mPreferences.getSync(KEY_TEST_BOOLEAN_ELEMENT, false); expect(true).assertEqual(per); await mPreferences.flush(); + data_preferences.removePreferencesFromCacheSync(context, NAME); + mPreferences = null; + mPreferences = data_preferences.getPreferencesSync(context, NAME); let per2 = mPreferences.getSync(KEY_TEST_BOOLEAN_ELEMENT, false); expect(true).assertEqual(per2); - done(); }) /** @@ -294,15 +268,16 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0100 * @tc.desc put float promise interface test */ - it('testPreferencesPutFloat0131', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutFloat0131', 0, async function () { mPreferences.putSync(KEY_TEST_FLOAT_ELEMENT, 4.0); let per = mPreferences.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0); expect(4.0).assertEqual(per); await mPreferences.flush(); + data_preferences.removePreferencesFromCacheSync(context, NAME); + mPreferences = null; + mPreferences = data_preferences.getPreferencesSync(context, NAME); let per2 = mPreferences.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0); expect(4.0).assertEqual(per2); - done(); }) /** @@ -310,15 +285,17 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0110 * @tc.desc put int promise interface test */ - it('testPreferencesPutInt0141', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutInt0141', 0, async function () { mPreferences.putSync(KEY_TEST_INT_ELEMENT, 4); let per = mPreferences.getSync(KEY_TEST_INT_ELEMENT, 0); expect(4).assertEqual(per); await mPreferences.flush(); + data_preferences.removePreferencesFromCacheSync(context, NAME); + mPreferences = null; + mPreferences = data_preferences.getPreferencesSync(context, NAME); let per2 = mPreferences.getSync(KEY_TEST_INT_ELEMENT, 0); expect(4).assertEqual(per2); - done(); + }) /** @@ -326,15 +303,17 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0120 * @tc.desc put long promise interface test */ - it('testPreferencesPutLong0151', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutLong0151', 0, async function () { mPreferences.putSync(KEY_TEST_LONG_ELEMENT, 4); let per = mPreferences.getSync(KEY_TEST_LONG_ELEMENT, 0); expect(4).assertEqual(per); await mPreferences.flush(); + data_preferences.removePreferencesFromCacheSync(context, NAME); + mPreferences = null; + mPreferences = data_preferences.getPreferencesSync(context, NAME); let per2 = mPreferences.getSync(KEY_TEST_LONG_ELEMENT, 0); expect(4).assertEqual(per2); - done(); + }) /** @@ -342,14 +321,16 @@ describe('preferencesSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0130 * @tc.desc put String promise interface test */ - it('testPreferencesPutString0161', 0, async function (done) { - mPreferences.clearSync(); + it('testPreferencesPutString0161', 0, async function () { mPreferences.putSync(KEY_TEST_STRING_ELEMENT, ''); let per = mPreferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect('').assertEqual(per); await mPreferences.flush(); + data_preferences.removePreferencesFromCacheSync(context, NAME); + mPreferences = null; + mPreferences = data_preferences.getPreferencesSync(context, NAME); let per2 = mPreferences.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue"); expect('').assertEqual(per2); - done(); + }) }) \ No newline at end of file diff --git a/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js b/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js index a4b4961b2cca9223290a370f82087a5d7f0ebc75..64129ff4dcd71e8e30b7a6ab6700eb3af0eb0e76 100644 --- a/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js @@ -26,12 +26,20 @@ var mPref; describe('StorageCallBackJsunit', function () { beforeAll(function () { console.info('beforeAll') + }) + + beforeEach( function () { + console.info('beforeEach'); mPref = storage.getStorageSync(PATH); }) + afterEach(function () { + console.info('afterEach'); + storage.deleteStorageSync(PATH); + }) + afterAll(function () { console.info('afterAll') - storage.deleteStorageSync(PATH); }) /** @@ -39,10 +47,10 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0010 * @tc.desc clear callback interface test */ - it('testClear0012', 0, async function (done) { + it('testClear0012', 0, function (done) { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); mPref.flushSync(); - await mPref.clear(function (err, ret) { + mPref.clear(function (err, ret) { expect("defaultvalue").assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); done(); }); @@ -53,9 +61,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0020 * @tc.desc has string callback interface test */ - it('testHasKey0032', 0, async function (done) { + it('testHasKey0032', 0, function (done) { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); - await mPref.has(KEY_TEST_STRING_ELEMENT, function (err, ret) { + mPref.has(KEY_TEST_STRING_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -66,9 +74,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0130 * @tc.desc has int callback interface test */ - it('testHasKey0033', 0, async function (done) { + it('testHasKey0033', 0, function (done) { mPref.putSync(KEY_TEST_INT_ELEMENT, 1); - await mPref.has(KEY_TEST_INT_ELEMENT, function (err, ret) { + mPref.has(KEY_TEST_INT_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -79,9 +87,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0140 * @tc.desc has float callback interface test */ - it('testHasKey0034', 0, async function (done) { + it('testHasKey0034', 0, function (done) { mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 1.1); - await mPref.has(KEY_TEST_FLOAT_ELEMENT, function (err, ret) { + mPref.has(KEY_TEST_FLOAT_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -92,9 +100,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0150 * @tc.desc has long callback interface test */ - it('testHasKey0035', 0, async function (done) { + it('testHasKey0035', 0, function (done) { mPref.putSync(KEY_TEST_LONG_ELEMENT, 0); - await mPref.has(KEY_TEST_LONG_ELEMENT, function (err, ret) { + mPref.has(KEY_TEST_LONG_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -105,9 +113,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0160 * @tc.desc has boolean callback interface test */ - it('testHasKey0036', 0, async function (done) { + it('testHasKey0036', 0, function (done) { mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); - await mPref.has(KEY_TEST_BOOLEAN_ELEMENT, function (err, ret) { + mPref.has(KEY_TEST_BOOLEAN_ELEMENT, function (err, ret) { expect(true).assertEqual(ret); done(); }) @@ -118,9 +126,8 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0030 * @tc.desc get defaultValue callback interface test */ - it('testGetDefValue0062', 0, async function (done) { - mPref.clearSync(); - await mPref.get(KEY_TEST_STRING_ELEMENT, "defaultValue", function (err, ret) { + it('testGetDefValue0062', 0, function (done) { + mPref.get(KEY_TEST_STRING_ELEMENT, "defaultValue", function (err, ret) { expect('defaultValue').assertEqual(ret); done(); }) @@ -131,10 +138,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0040 * @tc.desc get float callback interface test */ - it('testGetFloat0072', 0, async function (done) { - mPref.clearSync(); + it('testGetFloat0072', 0, function (done) { mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); - await mPref.get(KEY_TEST_FLOAT_ELEMENT, 0.0, function (err, ret) { + mPref.get(KEY_TEST_FLOAT_ELEMENT, 0.0, function (err, ret) { expect(3.0).assertEqual(ret); done(); }) @@ -145,10 +151,9 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0050 * @tc.desc get int callback interface test */ - it('testGetInt0082', 0, async function (done) { - mPref.clearSync(); + it('testGetInt0082', 0, function (done) { mPref.putSync(KEY_TEST_INT_ELEMENT, 3); - await mPref.get(KEY_TEST_INT_ELEMENT, 0.0, function (err, ret) { + mPref.get(KEY_TEST_INT_ELEMENT, 0.0, function (err, ret) { expect(3).assertEqual(ret); done(); }) @@ -159,11 +164,10 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0060 * @tc.desc get long callback interface test */ - it('testGetLong0092', 0, async function (done) { - mPref.clearSync(); + it('testGetLong0092', 0, function (done) { mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); expect(3).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); - await mPref.get(KEY_TEST_LONG_ELEMENT, 0, function (err, ret) { + mPref.get(KEY_TEST_LONG_ELEMENT, 0, function (err, ret) { expect(3).assertEqual(ret); done(); }); @@ -174,11 +178,10 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0070 * @tc.desc get String callback interface test */ - it('testGetString102', 0, async function (done) { - mPref.clearSync(); + it('testGetString102', 0, function (done) { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); mPref.flushSync(); - await mPref.get(KEY_TEST_STRING_ELEMENT, "defaultvalue", function (err, ret) { + mPref.get(KEY_TEST_STRING_ELEMENT, "defaultvalue", function (err, ret) { expect('test').assertEqual(ret); done(); }); @@ -189,11 +192,13 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0080 * @tc.desc put boolean callback interface test */ - it('testPutBoolean0122', 0, async function (done) { - mPref.clearSync(); - await mPref.put(KEY_TEST_BOOLEAN_ELEMENT, true, function (err, ret) { + it('testPutBoolean0122', 0, function (done) { + mPref.put(KEY_TEST_BOOLEAN_ELEMENT, true, function (err, ret) { expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); done(); }); @@ -204,11 +209,13 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0090 * @tc.desc put float callback interface test */ - it('testPutFloat0132', 0, async function (done) { - mPref.clearSync(); - await mPref.put(KEY_TEST_FLOAT_ELEMENT, 4.0, function (err, ret) { + it('testPutFloat0132', 0, function (done) { + mPref.put(KEY_TEST_FLOAT_ELEMENT, 4.0, function (err, ret) { expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); mPref.flushSync(); + storage.removeStorageFromCache(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); done(); }); @@ -219,11 +226,13 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0100 * @tc.desc put int callback interface test */ - it('testPutInt0142', 0, async function (done) { - mPref.clearSync(); - await mPref.put(KEY_TEST_INT_ELEMENT, 4, function (err, ret) { + it('testPutInt0142', 0, function (done) { + mPref.put(KEY_TEST_INT_ELEMENT, 4, function (err, ret) { expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCache(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); done(); }); @@ -234,12 +243,14 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0110 * @tc.desc put long callback interface test */ - it('testPutLong0152', 0, async function (done) { - mPref.clearSync(); + it('testPutLong0152', 0, function (done) { mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); - await mPref.put(KEY_TEST_LONG_ELEMENT, 4, function (err, ret) { + mPref.put(KEY_TEST_LONG_ELEMENT, 4, function (err, ret) { expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); done(); }); @@ -250,11 +261,13 @@ describe('StorageCallBackJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0120 * @tc.desc put String callback interface test */ - it('testPutString0162', 0, async function (done) { - mPref.clearSync(); - await mPref.put(KEY_TEST_STRING_ELEMENT, '', function (err, ret) { + it('testPutString0162', 0, function (done) { + mPref.put(KEY_TEST_STRING_ELEMENT, '', function (err, ret) { expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); done(); }); diff --git a/preferences/test/js/unittest/storage/src/StorageHelperJsunit.test.js b/preferences/test/js/unittest/storage/src/StorageHelperJsunit.test.js index 2f4ba0ec88c5d4d9613f2ef7da9f87118f78a9b4..497e106323ed7ab9b1f64e50c369a7a1dd9894c9 100644 --- a/preferences/test/js/unittest/storage/src/StorageHelperJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StorageHelperJsunit.test.js @@ -22,12 +22,20 @@ var mPref; describe('StorageHelperJsunit', function () { beforeAll(function () { console.info('beforeAll') + }) + + beforeEach(function () { + console.info('beforeEach'); mPref = storage.getStorageSync(PATH); }) + afterEach(function () { + console.info('afterEach'); + storage.deleteStorageSync(PATH); + }) + afterAll(function () { console.info('afterAll') - storage.deleteStorageSync(PATH); }) /** @@ -35,10 +43,8 @@ describe('StorageHelperJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0010 * @tc.desc getStorageSync interface test */ - it('testGetStorageHelper001', 0, function () { - mPref = storage.getStorageSync(PATH); + it('testGetStorageHelper001', 0, async function () { mPref.putSync('test', 2); - mPref.flushSync(); var value = mPref.getSync('test', 0); expect(value).assertEqual(2); }) @@ -48,18 +54,15 @@ describe('StorageHelperJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0020 * @tc.desc getStorage interface test */ - it('testGetStorageHelper002', 0, async function (done) { + it('testGetStorageHelper002', 0, async function () { const promise = storage.getStorage(PATH); - promise.then((pref) => { + await promise.then((pref) => { pref.putSync('test', 2); - pref.flushSync(); var value = mPref.getSync('test', 0); expect(value).assertEqual(2); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -68,32 +71,31 @@ describe('StorageHelperJsunit', function () { * @tc.desc removeStorageFromCacheSync interface test */ it('testRemoveStorageFromCache001', 0, function () { - let perf = storage.getStorageSync('/data/test_storage1'); + let perf = storage.getStorageSync('/data/storage/el2/database/test_storage1'); perf.putSync('test', 2); + perf.flushSync(); try { - storage.removeStorageFromCacheSync('/data/test_storage1'); + storage.removeStorageFromCacheSync('/data/storage/el2/database/test_storage1'); } catch (e) { expect(null).assertFail(); } - var value = mPref.getSync('test', 0); + perf = storage.getStorageSync('/data/storage/el2/database/test_storage1'); + var value = perf.getSync('test', 0); expect(value).assertEqual(2); }) - /** * @tc.name removeStorageFromCache interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0040 * @tc.desc removeStorageFromCache interface test */ - it('testRemoveStorageFromCache002', 0, async function (done) { + it('testRemoveStorageFromCache002', 0, async function () { let perf = storage.getStorageSync('/data/test_storage2'); perf = null; const promise = storage.removeStorageFromCache('/data/test_storage2'); - promise.then((pref) => { + await promise.then((pref) => { }).catch((err) => { expect(null).assertFail(); - }); - await promise; - done(); + }); }) /** @@ -120,15 +122,13 @@ describe('StorageHelperJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0060 * @tc.desc deleteStorage interface test */ - it('testDeleteStorageHelper002', 0, async function (done) { + it('testDeleteStorageHelper002', 0, async function () { let perf = storage.getStorageSync('/data/test_storage4'); perf = null; const promise = storage.deleteStorage('/data/test_storage4'); - promise.then((pref) => { + await promise.then((pref) => { }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) }) \ No newline at end of file diff --git a/preferences/test/js/unittest/storage/src/StoragePromiseJsunit.test.js b/preferences/test/js/unittest/storage/src/StoragePromiseJsunit.test.js index 11b28e19dd3f1373564931bab4fa6e43596d6cd0..61670192b8da4c2e1b52a8475bd2e55eb6a33f97 100644 --- a/preferences/test/js/unittest/storage/src/StoragePromiseJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StoragePromiseJsunit.test.js @@ -26,12 +26,20 @@ var mPref; describe('StoragePromiseJsunit', function () { beforeAll(function () { console.info('beforeAll') + }) + + beforeEach(function () { + console.info('beforeEach'); mPref = storage.getStorageSync(PATH); }) + afterEach(function () { + console.info('afterEach'); + storage.deleteStorageSync(PATH); + }) + afterAll(function () { console.info('afterAll') - storage.deleteStorageSync(PATH); }) /** @@ -39,17 +47,15 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Promise_0010 * @tc.desc clear promise interface test */ - it('testClear0011', 0, async function (done) { + it('testClear0011', 0, async function () { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); mPref.flushSync(); const promise = mPref.clear(); - promise.then((ret) => { + await promise.then((ret) => { expect("defaultvalue").assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -57,16 +63,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0020 * @tc.desc has string interface test */ - it('testHasKey0031', 0, async function (done) { + it('testHasKey0031', 0, async function () { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); const promise = mPref.has(KEY_TEST_STRING_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -74,16 +78,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0140 * @tc.desc has int interface test */ - it('testHasKey0032', 0, async function (done) { + it('testHasKey0032', 0, async function () { mPref.putSync(KEY_TEST_INT_ELEMENT, 1); const promise = mPref.has(KEY_TEST_INT_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -91,16 +93,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0150 * @tc.desc has float interface test */ - it('testHasKey0033', 0, async function (done) { + it('testHasKey0033', 0, async function () { mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 2.0); const promise = mPref.has(KEY_TEST_FLOAT_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -108,16 +108,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0160 * @tc.desc has boolean interface test */ - it('testHasKey0034', 0, async function (done) { + it('testHasKey0034', 0, async function () { mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); const promise = mPref.has(KEY_TEST_BOOLEAN_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -125,16 +123,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0170 * @tc.desc has long interface test */ - it('testHasKey0035', 0, async function (done) { + it('testHasKey0035', 0, async function () { mPref.putSync(KEY_TEST_LONG_ELEMENT, 0); const promise = mPref.has(KEY_TEST_LONG_ELEMENT); - promise.then((ret) => { + await promise.then((ret) => { expect(true).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -142,16 +138,13 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0030 * @tc.desc get string promise interface test */ - it('testGetDefValue0061', 0, async function (done) { - mPref.clearSync(); + it('testGetDefValue0061', 0, async function () { const promise = mPref.get(KEY_TEST_STRING_ELEMENT, "defaultValue"); - promise.then((ret) => { + await promise.then((ret) => { expect('defaultValue').assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -159,17 +152,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0040 * @tc.desc get float promise interface test */ - it('testGetFloat0071', 0, async function (done) { - mPref.clearSync(); + it('testGetFloat0071', 0, async function () { mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); const promise = mPref.get(KEY_TEST_FLOAT_ELEMENT, 0.0); - promise.then((ret) => { + await promise.then((ret) => { expect(3.0).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -177,17 +167,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0050 * @tc.desc get int promise interface test */ - it('testGetInt0081', 0, async function (done) { - mPref.clearSync(); + it('testGetInt0081', 0, async function () { mPref.putSync(KEY_TEST_INT_ELEMENT, 3); const promise = mPref.get(KEY_TEST_INT_ELEMENT, 0.0); - promise.then((ret) => { + await promise.then((ret) => { expect(3).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -195,17 +182,14 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0060 * @tc.desc get long promise interface test */ - it('testGetLong0091', 0, async function (done) { - mPref.clearSync(); + it('testGetLong0091', 0, async function () { mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); const promise = mPref.get(KEY_TEST_LONG_ELEMENT, 0); - promise.then((ret) => { + await promise.then((ret) => { expect(3).assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -213,18 +197,15 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0070 * @tc.desc get String promise interface test */ - it('testGetString101', 0, async function (done) { - mPref.clearSync(); + it('testGetString101', 0, async function () { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); mPref.flushSync(); const promise = mPref.get(KEY_TEST_STRING_ELEMENT, "defaultvalue"); - promise.then((ret) => { + await promise.then((ret) => { expect('test').assertEqual(ret); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -232,18 +213,18 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0090 * @tc.desc put boolean promise interface test */ - it('testPutBoolean0121', 0, async function (done) { - mPref.clearSync(); + it('testPutBoolean0121', 0, async function () { const promise = mPref.put(KEY_TEST_BOOLEAN_ELEMENT, true); - promise.then((ret) => { + await promise.then(async(ret) => { expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -251,18 +232,18 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0100 * @tc.desc put float promise interface test */ - it('testPutFloat0131', 0, async function (done) { - mPref.clearSync(); + it('testPutFloat0131', 0, async function () { const promise = mPref.put(KEY_TEST_FLOAT_ELEMENT, 4.0); - promise.then((ret) => { + await promise.then(async (ret) => { expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -270,18 +251,18 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0110 * @tc.desc put int promise interface test */ - it('testPutInt0141', 0, async function (done) { - mPref.clearSync(); + it('testPutInt0141', 0, async function () { const promise = mPref.put(KEY_TEST_INT_ELEMENT, 4); - promise.then((ret) => { + await promise.then(async (ret) => { expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -289,19 +270,19 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0120 * @tc.desc put long promise interface test */ - it('testPutLong0151', 0, async function (done) { - mPref.clearSync(); + it('testPutLong0151', 0, async function () { mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); const promise = mPref.put(KEY_TEST_LONG_ELEMENT, 4); - promise.then((ret) => { + await promise.then(async (ret) => { expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) /** @@ -309,18 +290,18 @@ describe('StoragePromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0130 * @tc.desc put String promise interface test */ - it('testPutString0161', 0, async function (done) { - mPref.clearSync(); + it('testPutString0161', 0, async function () { mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); const promise = mPref.put(KEY_TEST_STRING_ELEMENT, ''); - promise.then((ret) => { + await promise.then(async (ret) => { expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); }).catch((err) => { expect(null).assertFail(); }); - await promise; - done(); }) }) \ No newline at end of file diff --git a/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js b/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js index f49c46fc9ebdc941af22ebb4ec6b69b71a8d672c..2324968cb346db890b439734f5a95c1575a47c56 100644 --- a/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js @@ -27,12 +27,20 @@ var mPref; describe('StorageSyncJsunit', function () { beforeAll(function() { console.info('beforeAll') - mPref = storage.getStorageSync(PATH); + }) + + beforeEach(async function () { + console.info('beforeEach'); + mPref = await storage.getStorageSync(PATH); + }) + + afterEach(async function () { + console.info('afterEach'); + await storage.deleteStorageSync(PATH); }) afterAll(function () { console.info('afterAll') - storage.deleteStorageSync(PATH); }) it('testClear001', 0, function () { @@ -56,7 +64,7 @@ describe('StorageSyncJsunit', function () { /** * @tc.name put string sync interface test * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0020 - * @tc.desc put string sync interface test + * @tc.desc put string sync interface test */ it('testHasKey003', 0, function () { mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); @@ -119,7 +127,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc get defaultValue sync interface test */ it('testGetDefValue006', 0, function () { - mPref.clearSync(); expect(-1).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, -1)); expect(1.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 1.0)); expect(10000).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 10000)); @@ -133,7 +140,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc put float sync interface test */ it('testGetFloat007', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); expect(3.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); expect(0.0).assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, 0.0)); @@ -145,7 +151,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc put int sync interface test */ it('testGetInt008', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_INT_ELEMENT, 3); expect(3).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0.0)); }) @@ -156,7 +161,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc put long sync interface test */ it('testGetLong009', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); expect(3).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); expect(0).assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, 0)); @@ -168,7 +172,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc put String & int sync interface test */ it('testGetString10', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); mPref.putSync(KEY_TEST_INT_ELEMENT, 3); mPref.flushSync(); @@ -182,10 +185,12 @@ describe('StorageSyncJsunit', function () { * @tc.desc put boolean sync interface test */ it('testPutBoolean012', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, true); expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); }) @@ -195,10 +200,12 @@ describe('StorageSyncJsunit', function () { * @tc.desc put float sync interface test */ it('testPutFloat013', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 4.0); expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); }) @@ -207,11 +214,13 @@ describe('StorageSyncJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0110 * @tc.desc put int sync interface test */ - it('testPutInt014', 0, function () { - mPref.clearSync(); + it('testPutInt014', 0, function () {; mPref.putSync(KEY_TEST_INT_ELEMENT, 4); expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); }) @@ -221,10 +230,12 @@ describe('StorageSyncJsunit', function () { * @tc.desc put long sync interface test */ it('testPutLong015', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); }) @@ -234,11 +245,13 @@ describe('StorageSyncJsunit', function () { * @tc.desc put String sync interface test */ it('testPutString016', 0, function () { - mPref.clearSync(); mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); mPref.putSync(KEY_TEST_STRING_ELEMENT, ''); expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); mPref.flushSync(); + storage.removeStorageFromCacheSync(PATH); + mPref = null; + mPref = storage.getStorageSync(PATH); expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); }) @@ -248,7 +261,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc put interface test */ it('testRegisterObserver001', 0, function () { - mPref.clearSync(); var observer = function (key) { expect('abcd').assertEqual(key); }; @@ -262,7 +274,6 @@ describe('StorageSyncJsunit', function () { * @tc.desc repeat on interface test */ it('testRegisterObserver002', 0, function () { - mPref.clearSync(); var observer = function (key) { console.info('testRegisterObserver001 key' + key); expect('abc').assertEqual(key); diff --git a/preferences/test/js/unittest/system_storage/src/SystemStorageJsunit.test.js b/preferences/test/js/unittest/system_storage/src/SystemStorageJsunit.test.js index b58884d637608547006383321397337a773c02aa..372443d59115d1dede2266eed98a5e1cc17bda44 100644 --- a/preferences/test/js/unittest/system_storage/src/SystemStorageJsunit.test.js +++ b/preferences/test/js/unittest/system_storage/src/SystemStorageJsunit.test.js @@ -23,7 +23,7 @@ describe('SystemStorageJsunit', function () { afterEach(async function (done) { console.info(TAG + 'afterEach') - let promise = storage.clear({ + await storage.clear({ success: function () { expect(true).assertTrue(); done(); @@ -33,8 +33,6 @@ describe('SystemStorageJsunit', function () { done(); } }); - await promise; - done(); }) /** @@ -42,11 +40,11 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0001 * @tc.desc set and can get correct value in success callback, finally get complete callback */ - it('testSet001', 0, async function (done) { + it('testSet001', 0, async function () { console.log(TAG + '************* testSet001 start *************'); let completeRet = false; let successRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey', value: 'testVal', success: async function () { @@ -58,19 +56,14 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }); - await promise1; - let promise2 = storage.get({ + await storage.get({ key: 'storageKey', success: async function (data) { await expect(data).assertEqual('testVal'); } }) - await promise2; - await expect(successRet).assertTrue(); await expect(completeRet).assertTrue(); - done(); - console.log(TAG + '************* testSet001 end *************'); }) @@ -79,12 +72,12 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0002 * @tc.desc set null key can receive fail callback */ - it('testSet002', 0, async function (done) { + it('testSet002', 0, async function () { console.log(TAG + '************* testSet002 start *************'); let testData = undefined; let testErrCode = undefined; let compelteRet = false; - let promise = storage.set({ + await storage.set({ key: '', value: 'testValue', success: async function () { @@ -99,13 +92,9 @@ describe('SystemStorageJsunit', function () { await expect(compelteRet).assertTrue(); } }) - await promise; await expect("The key string is null or empty.").assertEqual(testData); await expect(-1006).assertEqual(testErrCode); await expect(compelteRet).assertTrue(); - - done(); - console.log(TAG + '************* testSet002 end *************'); }) @@ -114,12 +103,12 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0003 * @tc.desc set key which size over 32 bytes and can receive fail callback */ - it('testSet003', 0, async function (done) { + it('testSet003', 0, async function () { console.log(TAG + '************* testSet003 start *************'); let testData = undefined; let testErrCode = undefined; let compelteRet = false; - let promise = storage.set({ + await storage.set({ key: 'x'.repeat(33), value: 'testValue', success: async function () { @@ -134,13 +123,9 @@ describe('SystemStorageJsunit', function () { await expect(compelteRet).assertTrue(); } }) - await promise; await expect("The key string length should shorter than 32.").assertEqual(testData); await expect(-1016).assertEqual(testErrCode); await expect(compelteRet).assertTrue(); - - done(); - console.log(TAG + '************* testSet003 end *************'); }) @@ -150,12 +135,12 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0004 * @tc.desc set value which size over 128 bytes and can receive fail callback */ - it('testSet004', 0, async function (done) { + it('testSet004', 0, async function () { console.log(TAG + '************* testSet004 start *************'); let testData = undefined; let testErrCode = undefined; let compelteRet = false; - let promise = storage.set({ + await storage.set({ key: 'testKey', value: 'x'.repeat(129), success: async function () { @@ -169,13 +154,9 @@ describe('SystemStorageJsunit', function () { compelteRet = true; } }) - await promise; await expect("The value string length should shorter than 128.").assertEqual(testData); await expect(-1017).assertEqual(testErrCode); await expect(compelteRet).assertTrue(); - - done(); - console.log(TAG + '************* testSet004 end *************'); }) @@ -184,10 +165,10 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0001 * @tc.desc set and can get correct value in success callback, finally receive a get complete callback */ - it('testGet001', 0, async function (done) { + it('testGet001', 0, async function () { console.log(TAG + '************* testGet001 start *************'); let completeRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey', value: 'storageVal', success: async function () { @@ -197,8 +178,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }); - await promise1; - let promise2 = storage.get({ + await storage.get({ key: 'storageKey', success: async function (data) { await expect('storageVal').assertEqual(data); @@ -208,11 +188,7 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }); - await promise2; await expect(completeRet).assertTrue(); - - done(); - console.log(TAG + '************* testGet001 end *************'); }) @@ -221,10 +197,10 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0002 * @tc.desc get value without set any value and can get default in success callback */ - it('testGet002', 0, async function (done) { + it('testGet002', 0, async function () { console.log(TAG + '************* testGet002 start *************'); let completeRet = false; - let promise = storage.get({ + await storage.get({ key: 'storageKey', default: '123', success: async function (data) { @@ -238,11 +214,7 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }) - await promise; await expect(completeRet).assertTrue(); - - done(); - console.log(TAG + '************* testGet002 end *************'); }) @@ -252,14 +224,14 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0003 * @tc.desc get default size over 128 and can receive fail callback */ - it('testGet003', 0, async function (done) { + it('testGet003', 0, async function () { console.log(TAG + '************* testGet003 start *************'); let testVal = undefined; let testData = undefined; let testErrCode = undefined; let completeRet = false; let failRet = false; - let promise = storage.get({ + await storage.get({ key: 'storageKey', default: 'x'.repeat(129), success: async function (data) { @@ -275,15 +247,11 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }) - await promise; expect(failRet).assertTrue(); expect(completeRet).assertTrue(); expect(-1018).assertEqual(testErrCode); expect('The default string length should shorter than 128.').assertEqual(testData); expect(testVal == undefined).assertTrue(); - - done(); - console.log(TAG + '************* testGet003 end *************'); }) @@ -292,11 +260,11 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0004 * @tc.desc get null key and can return default value */ - it('testGet004', 0, async function (done) { + it('testGet004', 0, async function () { console.log(TAG + '************* testGet004 start *************'); let testVal = undefined; let completeRet = false; - let promise = storage.get({ + await storage.get({ key: '', default: 'storageVal', success: async function (data) { @@ -310,11 +278,7 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }) - await promise; await expect(completeRet).assertTrue(); - - done(); - console.log(TAG + '************* testGet004 end *************'); }) @@ -323,11 +287,11 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Delete_0001 * @tc.desc delete value and can not get value */ - it('testDelete001', 0, async function (done) { + it('testDelete001', 0, async function () { console.log(TAG + '************* testDelete001 start *************'); let completeRet = false; let successRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey', value: 'storageVal', success: async function () { @@ -337,8 +301,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }) - await promise1; - let promise2 = storage.delete({ + await storage.delete({ key: "storageKey", success: async function () { successRet = true; @@ -349,20 +312,15 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }); - await promise2; - let promise3 = storage.get({ + await storage.get({ key: 'storageKey', default: 'testVal', success: async function (data) { await expect(data).assertEqual('testVal'); } }) - await promise3; await expect(completeRet).assertTrue(); await expect(successRet).assertTrue(); - - done(); - console.log(TAG + '************* testDelete001 end *************'); }) @@ -371,13 +329,13 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Delete_0002 * @tc.desc delete null key and can get fail callback */ - it('testDelete002', 0, async function (done) { + it('testDelete002', 0, async function () { console.log(TAG + '************* testDelete002 start *************'); let testData = undefined; let testErrCode = undefined; let completeRet = false; let failRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey', value: 'storageVal', success: async function () { @@ -387,8 +345,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }) - await promise1; - let promise2 = storage.delete({ + await storage.delete({ key: '', success: async function () { await expect(false).assertTrue(); @@ -403,14 +360,10 @@ describe('SystemStorageJsunit', function () { await expect(completeRet).assertTrue(); } }) - await promise2; await expect(completeRet).assertTrue(); await expect("The key string is null or empty.").assertEqual(testData); await expect(-1006).assertEqual(testErrCode); await expect(failRet).assertTrue(); - - done(); - console.log(TAG + '************* testDelete002 end *************'); }) @@ -419,10 +372,10 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Delete_0003 * @tc.desc delete incorrect key and can get success callback */ - it('testDelete003', 0, async function (done) { + it('testDelete003', 0, async function () { console.log(TAG + '************* testDelete003 start *************'); let completeRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey', value: 'test', success: async function () { @@ -432,8 +385,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }); - await promise1; - let promise2 = storage.delete({ + await storage.delete({ key: '123', success: async function () { await expect(true).assertTrue(); @@ -446,8 +398,7 @@ describe('SystemStorageJsunit', function () { expect(completeRet).assertTrue(); } }); - await promise2; - let promise3 = storage.get({ + await storage.get({ key: 'storageKey', success: async function (data) { await expect(data).assertEqual('test'); @@ -456,11 +407,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); } }) - await promise3; await expect(completeRet).assertTrue(); - - done(); - console.log(TAG + '************* testDelete003 end *************'); }) @@ -469,10 +416,10 @@ describe('SystemStorageJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Clear_0001 * @tc.desc clear and can receive success callback */ - it('testClear001', 0, async function (done) { + it('testClear001', 0, async function () { console.log(TAG + '************* testClear001 start *************'); let successRet = false; - let promise1 = storage.set({ + await storage.set({ key: 'storageKey1', value: 'storageVal1', success:async function () { @@ -482,8 +429,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }); - await promise1; - let promise2 = storage.set({ + await storage.set({ key: 'storageKey2', value: 'storageVal2', success:async function () { @@ -493,8 +439,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); }, }); - await promise2; - let promise3 = storage.clear({ + await storage.clear({ success:async function() { successRet = true; await expect(successRet).assertTrue(); @@ -503,11 +448,7 @@ describe('SystemStorageJsunit', function () { await expect(false).assertTrue(); } }); - await promise3; await expect(successRet).assertTrue(); - - done(); - console.log(TAG + '************* testClear001 end *************'); }) diff --git a/preferences/test/native/unittest/preferences_file_test.cpp b/preferences/test/native/unittest/preferences_file_test.cpp index 8addb083f5287901be32dcf5eeec0b19ef78dd3e..39576849cb036a4504c2069c5698f8ae36e5d16a 100644 --- a/preferences/test/native/unittest/preferences_file_test.cpp +++ b/preferences/test/native/unittest/preferences_file_test.cpp @@ -52,6 +52,15 @@ void PreferencesFileTest::TearDown(void) { } +int PreferencesPutValue(std::shared_ptr pref, const std::string &intKey, int intValue, + const std::string &strKey, const std::string &strValue) +{ + pref->PutInt(intKey, intValue); + pref->PutString(strKey, strValue); + int ret = pref->FlushSync(); + return ret; +} + /** * @tc.name: NativePreferencesFileTest_001 * @tc.desc: normal testcase of backup file @@ -73,7 +82,7 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_001, TestSize.Level1) elem.tag_ = std::string("int"); elem.value_ = std::to_string(10); settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(backupFile, settings); + PreferencesXmlUtils::WriteSettingXml(backupFile, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -108,9 +117,7 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_002, TestSize.Level1) std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); EXPECT_EQ(errCode, E_OK); - pref->PutInt("key1", 2); - pref->PutString("key2", "test"); - int ret = pref->FlushSync(); + int ret = PreferencesPutValue(pref, "key1", 2, "key2", "test"); EXPECT_EQ(ret, E_OK); struct stat st = { 0 }; @@ -141,9 +148,7 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_003, TestSize.Level1) std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); EXPECT_EQ(errCode, E_OK); - pref->PutInt("intKey", 1); - pref->PutString("stringKey", "string1"); - ret = pref->FlushSync(); + ret = PreferencesPutValue(pref, "intKey", 1, "stringKey", "string1"); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, pref->GetInt("intKey", 0)); @@ -160,25 +165,10 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_003, TestSize.Level1) EXPECT_EQ(1, pref->GetInt("intKey", 0)); EXPECT_EQ("string1", pref->GetString("stringKey", "")); - pref->PutInt("intKey", 2); - pref->PutString("stringKey", "string2"); - ret = pref->FlushSync(); - EXPECT_EQ(ret, E_OK); - pref->PutInt("intKey", 3); - pref->PutString("stringKey", "string3"); - ret = pref->FlushSync(); - EXPECT_EQ(ret, E_OK); - - pref->PutInt("intKey", 4); - pref->PutString("stringKey", "string4"); - ret = pref->FlushSync(); - EXPECT_EQ(ret, E_OK); - - pref = PreferencesHelper::GetPreferences(file, errCode); - pref->PutInt("intKey", 5); - pref->PutString("stringKey", "string5"); - ret = pref->FlushSync(); - EXPECT_EQ(ret, E_OK); + for (int i = 2; i <= 5; i++) { + ret = PreferencesPutValue(pref, "intKey", i, "stringKey", "string" + std::to_string(i)); + EXPECT_EQ(ret, E_OK); + } EXPECT_EQ(5, pref->GetInt("intKey", 0)); EXPECT_EQ("string5", pref->GetString("stringKey", "")); @@ -216,9 +206,8 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_004, TestSize.Level3) std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); EXPECT_EQ(errCode, E_OK); - pref->PutInt("intKey", 1); - pref->PutString("stringKey", "string1"); - pref->Flush(); + ret = PreferencesPutValue(pref, "intKey", 1, "stringKey", "string1"); + EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, pref->GetInt("intKey", 0)); EXPECT_EQ("string1", pref->GetString("stringKey", "")); @@ -236,20 +225,10 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_004, TestSize.Level3) EXPECT_EQ(1, pref->GetInt("intKey", 0)); EXPECT_EQ("string1", pref->GetString("stringKey", "")); - pref->PutInt("intKey", 2); - pref->PutString("stringKey", "string2"); - pref->Flush(); - pref->PutInt("intKey", 3); - pref->PutString("stringKey", "string3"); - pref->Flush(); - - pref->PutInt("intKey", 4); - pref->PutString("stringKey", "string4"); - pref->Flush(); - - pref->PutInt("intKey", 5); - pref->PutString("stringKey", "string5"); - pref->Flush(); + for (int i = 2; i <= 5; i++) { + ret = PreferencesPutValue(pref, "intKey", i, "stringKey", "string" + std::to_string(i)); + EXPECT_EQ(ret, E_OK); + } EXPECT_EQ(5, pref->GetInt("intKey", 0)); EXPECT_EQ("string5", pref->GetString("stringKey", "")); diff --git a/preferences/test/native/unittest/preferences_xml_utils_test.cpp b/preferences/test/native/unittest/preferences_xml_utils_test.cpp index 5ca90a1adae76cb0d571e35d7b34417bce2fe58f..de3907a2c099506450be0fd0abb76d0ef9d6b4c2 100644 --- a/preferences/test/native/unittest/preferences_xml_utils_test.cpp +++ b/preferences/test/native/unittest/preferences_xml_utils_test.cpp @@ -54,24 +54,72 @@ void PreferencesXmlUtilsTest::TearDown(void) } /** -* @tc.name: NativePreferencesImplTest_001 -* @tc.desc: normal testcase of DeletePreferences +* @tc.name: ReadSettingXmlTest_001 +* @tc.desc: normal testcase of ReadSettingXml * @tc.type: FUNC */ -HWTEST_F(PreferencesXmlUtilsTest, NativePreferencesHelperTest_001, TestSize.Level1) +HWTEST_F(PreferencesXmlUtilsTest, ReadSettingXmlTest_001, TestSize.Level1) { std::vector settings = {}; - bool ret = PreferencesXmlUtils::ReadSettingXml("", settings); + bool ret = PreferencesXmlUtils::ReadSettingXml("", "", settings); EXPECT_EQ(ret, false); std::string path = "/data/test/test_helper" + std::string(4096, 't'); - ret = PreferencesXmlUtils::ReadSettingXml(path, settings); + ret = PreferencesXmlUtils::ReadSettingXml(path, "", settings); EXPECT_EQ(ret, false); - ret = PreferencesXmlUtils::ReadSettingXml("data/test/test_helper", settings); + ret = PreferencesXmlUtils::ReadSettingXml("data/test/test_helper", "", settings); EXPECT_EQ(ret, false); } +/** +* @tc.name: ReadSettingXmlTest_002 +* @tc.desc: ReadSettingXml testcase of PreferencesXmlUtils, reading a corrupt file +* @tc.type: FUNC +*/ +HWTEST_F(PreferencesXmlUtilsTest, ReadSettingXmlTest_002, TestSize.Level1) +{ + std::string fileName = "/data/test/test01"; + + std::ofstream oss(fileName); + oss << "corrupted"; + + int errCode = E_OK; + std::shared_ptr pref = PreferencesHelper::GetPreferences(fileName, errCode); + EXPECT_EQ(errCode, E_OK); + + int ret = PreferencesHelper::DeletePreferences(fileName); + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: ReadSettingXmlTest_003 +* @tc.desc: ReadSettingXml testcase of PreferencesXmlUtils, no empty dataGroupId +* @tc.type: FUNC +*/ +HWTEST_F(PreferencesXmlUtilsTest, ReadSettingXmlTest_003, TestSize.Level1) +{ + std::string file = "/data/test/test01"; + + std::vector settings; + Element elem; + elem.key_ = "testKet"; + elem.tag_ = "int"; + elem.value_ = "999"; + settings.push_back(elem); + PreferencesXmlUtils::WriteSettingXml(file, "123456", settings); + + std::vector settingsRes = {}; + bool ret = PreferencesXmlUtils::ReadSettingXml(file, "123456", settingsRes); + EXPECT_EQ(ret, true); + EXPECT_EQ(settingsRes.empty(), false); + EXPECT_EQ(elem.key_, settingsRes.front().key_); + EXPECT_EQ(elem.tag_, settingsRes.front().tag_); + EXPECT_EQ(elem.value_, settingsRes.front().value_); + + std::remove(file.c_str()); +} + /** * @tc.name: UnnormalReadSettingXml_001 * @tc.desc: unnormal testcase of ReadSettingXml @@ -80,22 +128,22 @@ HWTEST_F(PreferencesXmlUtilsTest, NativePreferencesHelperTest_001, TestSize.Leve HWTEST_F(PreferencesXmlUtilsTest, UnnormalReadSettingXml_001, TestSize.Level1) { std::vector settings = {}; - PreferencesXmlUtils::WriteSettingXml("", settings); - bool ret = PreferencesXmlUtils::ReadSettingXml("", settings); + PreferencesXmlUtils::WriteSettingXml("", "", settings); + bool ret = PreferencesXmlUtils::ReadSettingXml("", "", settings); EXPECT_EQ(ret, false); std::string path = "/data/test/test_helper" + std::string(4096, 't'); - ret = PreferencesXmlUtils::ReadSettingXml(path, settings); + ret = PreferencesXmlUtils::ReadSettingXml(path, "", settings); EXPECT_EQ(ret, false); - ret = PreferencesXmlUtils::ReadSettingXml("data/test/test_helper", settings); + ret = PreferencesXmlUtils::ReadSettingXml("data/test/test_helper", "", settings); EXPECT_EQ(ret, false); Element elem; settings.push_back(elem); path = "data/test/test_helper"; - PreferencesXmlUtils::WriteSettingXml(path, settings); - ret = PreferencesXmlUtils::ReadSettingXml(path, settings); + PreferencesXmlUtils::WriteSettingXml(path, "", settings); + ret = PreferencesXmlUtils::ReadSettingXml(path, "", settings); EXPECT_EQ(ret, false); } @@ -115,7 +163,7 @@ HWTEST_F(PreferencesXmlUtilsTest, StringNodeElementTest_001, TestSize.Level1) elem.tag_ = std::string("string"); elem.value_ = "test"; settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -153,7 +201,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_001, TestSize.Level1) elem.children_.push_back(elemChild); settings.push_back(elem); std::vector inputStringArray = { "test_child1", "test_child2" }; - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -193,7 +241,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_002, TestSize.Level1) elem.children_.push_back(elemChild); settings.push_back(elem); std::vector inputDoubleArray = { 1.0, 2.0 }; - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -233,7 +281,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_003, TestSize.Level1) elem.children_.push_back(elemChild); settings.push_back(elem); std::vector inputBoolArray = { false, true }; - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -263,7 +311,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_004, TestSize.Level1) elem.value_ = std::to_string(false); settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -295,7 +343,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_005, TestSize.Level1) elem.value_ = std::to_string(false); settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -327,7 +375,7 @@ HWTEST_F(PreferencesXmlUtilsTest, ArrayNodeElementTest_006, TestSize.Level1) elem.value_ = std::to_string(1); settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(file, settings); + PreferencesXmlUtils::WriteSettingXml(file, "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(file, errCode); @@ -361,7 +409,7 @@ HWTEST_F(PreferencesXmlUtilsTest, RenameToBrokenFileTest_001, TestSize.Level1) elem.value_ = "2"; settings.push_back(elem); - PreferencesXmlUtils::WriteSettingXml(PreferencesImpl::MakeFilePath(fileName, STR_BACKUP), settings); + PreferencesXmlUtils::WriteSettingXml(PreferencesImpl::MakeFilePath(fileName, STR_BACKUP), "", settings); int errCode = E_OK; std::shared_ptr pref = PreferencesHelper::GetPreferences(fileName, errCode); @@ -373,24 +421,4 @@ HWTEST_F(PreferencesXmlUtilsTest, RenameToBrokenFileTest_001, TestSize.Level1) int ret = PreferencesHelper::DeletePreferences(fileName); EXPECT_EQ(ret, E_OK); } - -/** -* @tc.name: ReadSettingXml_001 -* @tc.desc: ReadSettingXml testcase of PreferencesXmlUtils, reading a corrupt file -* @tc.type: FUNC -*/ -HWTEST_F(PreferencesXmlUtilsTest, ReadSettingXml_001, TestSize.Level1) -{ - std::string fileName = "/data/test/test01"; - - std::ofstream oss(fileName); - oss << "corrupted"; - - int errCode = E_OK; - std::shared_ptr pref = PreferencesHelper::GetPreferences(fileName, errCode); - EXPECT_EQ(errCode, E_OK); - - int ret = PreferencesHelper::DeletePreferences(fileName); - EXPECT_EQ(ret, E_OK); -} } diff --git a/relational_store/CMakeLists.txt b/relational_store/CMakeLists.txt index 4cf500e748c1942acfbb16f0690cd90b0ee01269..b5c5ec0f2a31ed0f9c35bd629ba68b88cb8e05ee 100644 --- a/relational_store/CMakeLists.txt +++ b/relational_store/CMakeLists.txt @@ -17,6 +17,8 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/dataability/ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/relationalstore/src js_relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/src js_rdb_store_src) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/ndk/src ndk_rdb_store_src) + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/src relational_store_src) list(REMOVE_ITEM relational_store_src "${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/src/general_endian.cpp") @@ -63,6 +65,11 @@ add_library(js_rdb_store SHARED ${js_common_src} ${js_rdb_store_src}) target_link_libraries(js_rdb_store ${links} relational_store) target_include_directories(js_rdb_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/include) +add_library(ndk_rdb_store SHARED ${ndk_rdb_store_src}) +target_link_libraries(ndk_rdb_store ${links} relational_store) +target_include_directories(ndk_rdb_store PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/ndk/include) +target_include_directories(ndk_rdb_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/ndk/src) + add_library(js_dataability SHARED ${js_common_src} ${js_dataability_src}) target_link_libraries(js_dataability mock relational_store js_rdb_store) target_include_directories(js_dataability PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/include) diff --git a/relational_store/frameworks/js/napi/cloud_data/include/js_error_utils.h b/relational_store/frameworks/js/napi/cloud_data/include/js_error_utils.h index 93d9d5d0b8438ae1632d23d8f99e2d67bdff90ea..f40f5a9aad08cd796b2b794c50cfa36a9928dd69 100644 --- a/relational_store/frameworks/js/napi/cloud_data/include/js_error_utils.h +++ b/relational_store/frameworks/js/napi/cloud_data/include/js_error_utils.h @@ -28,9 +28,9 @@ namespace CloudData { using Status = OHOS::CloudData::CloudService::Status; struct JsErrorCode { - int32_t status; - int32_t jsCode; - const char *message; + int32_t status = 0; + int32_t jsCode = -1; + const char *message = nullptr; }; const std::optional GetJsErrorCode(int32_t errorCode); diff --git a/relational_store/frameworks/js/napi/common/include/js_utils.h b/relational_store/frameworks/js/napi/common/include/js_utils.h index 1a50f88401e67dc1fa765bd653ede5f97f8ecb72..611c43786b783ba4387a6cf5b62b5eb87a5554c3 100644 --- a/relational_store/frameworks/js/napi/common/include/js_utils.h +++ b/relational_store/frameworks/js/napi/common/include/js_utils.h @@ -70,6 +70,8 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, std::map int32_t Convert2Value(napi_env env, napi_value jsValue, T &output); diff --git a/relational_store/frameworks/js/napi/common/src/js_utils.cpp b/relational_store/frameworks/js/napi/common/src/js_utils.cpp index 737f5fa1e4e2cd5be3b6119346313892ff3e58c1..eb470eb7e09c359bd9cf7535f8055a99b9b8c944 100644 --- a/relational_store/frameworks/js/napi/common/src/js_utils.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_utils.cpp @@ -69,7 +69,7 @@ std::string JSUtils::Convert2String(napi_env env, napi_value jsStr) int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, uint32_t &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_number) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -86,7 +86,7 @@ int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, uint32_t &ou int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, int32_t &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_number) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -103,7 +103,7 @@ int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, int32_t &out int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, bool &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_boolean) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -122,7 +122,7 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, bool &output) int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, int64_t &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_number) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -139,7 +139,7 @@ int32_t JSUtils::Convert2ValueExt(napi_env env, napi_value jsValue, int64_t &out int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, double &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_number) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -163,7 +163,7 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, int64_t &output int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::string &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_string) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -218,7 +218,7 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::vector &value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_array_with_length(env, value.size(), &jsValue); if (status != napi_ok) { return nullptr; @@ -304,7 +304,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector napi_value JSUtils::Convert2JSValue(napi_env env, const std::string &value) { - napi_value jsValue; + napi_value jsValue = nullptr; if (napi_create_string_utf8(env, value.c_str(), value.size(), &jsValue) != napi_ok) { return nullptr; } @@ -313,7 +313,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, const std::string &value) napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector &value) { - napi_value jsValue; + napi_value jsValue = nullptr; void *native = nullptr; napi_value buffer = nullptr; napi_status status = napi_create_arraybuffer(env, value.size(), &native, &buffer); @@ -332,7 +332,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector &va napi_value JSUtils::Convert2JSValue(napi_env env, int32_t value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_int32(env, value, &jsValue); if (status != napi_ok) { return nullptr; @@ -342,7 +342,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, int32_t value) napi_value JSUtils::Convert2JSValue(napi_env env, uint32_t value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_uint32(env, value, &jsValue); if (status != napi_ok) { return nullptr; @@ -352,7 +352,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, uint32_t value) napi_value JSUtils::Convert2JSValue(napi_env env, int64_t value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_int64(env, value, &jsValue); if (status != napi_ok) { return nullptr; @@ -362,7 +362,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, int64_t value) napi_value JSUtils::Convert2JSValue(napi_env env, double value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_double(env, value, &jsValue); if (status != napi_ok) { return nullptr; @@ -372,7 +372,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, double value) napi_value JSUtils::Convert2JSValue(napi_env env, bool value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_get_boolean(env, value, &jsValue); if (status != napi_ok) { return nullptr; @@ -382,7 +382,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, bool value) napi_value JSUtils::Convert2JSValue(napi_env env, const std::map &value) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_array_with_length(env, value.size(), &jsValue); if (status != napi_ok) { return nullptr; @@ -390,7 +390,7 @@ napi_value JSUtils::Convert2JSValue(napi_env env, const std::map - +#include "js_uv_queue.h" #include "logger.h" namespace OHOS::AppDataMgrJsKit { @@ -78,7 +76,7 @@ void UvQueue::AsyncCall(UvCallback callback, ArgsGenerator genArgs) } napi_value global = nullptr; napi_get_global(entry->env, &global); - napi_value result; + napi_value result = nullptr; napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); if (status != napi_ok) { LOG_ERROR("notify data change failed status:%{public}d.", status); diff --git a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp index 92e5b728dce56edec58cb7282b5e4355d83e7202..778c003f1656b8398b2bccc19c0cd34f198d721a 100644 --- a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp +++ b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp @@ -74,7 +74,7 @@ void DataAbilityPredicatesProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_GETTER("isSorted", IsSorted), }; - napi_value cons; + napi_value cons = nullptr; NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "DataAbilityPredicates", NAPI_AUTO_LENGTH, New, nullptr, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons)); @@ -85,11 +85,11 @@ void DataAbilityPredicatesProxy::Init(napi_env env, napi_value exports) napi_value DataAbilityPredicatesProxy::New(napi_env env, napi_callback_info info) { - napi_value new_target; + napi_value new_target = nullptr; NAPI_CALL(env, napi_get_new_target(env, info, &new_target)); bool is_constructor = (new_target != nullptr); - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); if (is_constructor) { @@ -107,10 +107,10 @@ napi_value DataAbilityPredicatesProxy::New(napi_env env, napi_callback_info info return thiz; } - napi_value cons; + napi_value cons = nullptr; NAPI_CALL(env, napi_get_reference_value(env, constructor_, &cons)); - napi_value output; + napi_value output = nullptr; NAPI_CALL(env, napi_new_instance(env, cons, 0, nullptr, &output)); return output; @@ -119,7 +119,7 @@ napi_value DataAbilityPredicatesProxy::New(napi_env env, napi_callback_info info napi_value DataAbilityPredicatesProxy::NewInstance( napi_env env, std::shared_ptr value) { - napi_value cons; + napi_value cons = nullptr; napi_status status = napi_get_reference_value(env, constructor_, &cons); if (status != napi_ok) { LOG_ERROR("DataAbilityPredicatesProxy get constructor failed! napi_status:%{public}d!", status); @@ -177,7 +177,7 @@ std::shared_ptr DataAbilityPredicatesProxy::Ge napi_env env, napi_callback_info info) { DataAbilityPredicatesProxy *predicatesProxy = nullptr; - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); return predicatesProxy->predicates_; @@ -185,7 +185,7 @@ std::shared_ptr DataAbilityPredicatesProxy::Ge napi_value DataAbilityPredicatesProxy::EqualTo(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -202,7 +202,7 @@ napi_value DataAbilityPredicatesProxy::EqualTo(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::NotEqualTo(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -219,7 +219,7 @@ napi_value DataAbilityPredicatesProxy::NotEqualTo(napi_env env, napi_callback_in napi_value DataAbilityPredicatesProxy::BeginWrap(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); auto nativePredicates = GetNativePredicates(env, info); RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); @@ -229,7 +229,7 @@ napi_value DataAbilityPredicatesProxy::BeginWrap(napi_env env, napi_callback_inf napi_value DataAbilityPredicatesProxy::EndWrap(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); auto nativePredicates = GetNativePredicates(env, info); RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); @@ -239,7 +239,7 @@ napi_value DataAbilityPredicatesProxy::EndWrap(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::Or(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); auto nativePredicates = GetNativePredicates(env, info); RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); @@ -249,7 +249,7 @@ napi_value DataAbilityPredicatesProxy::Or(napi_env env, napi_callback_info info) napi_value DataAbilityPredicatesProxy::And(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); auto nativePredicates = GetNativePredicates(env, info); RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); @@ -259,7 +259,7 @@ napi_value DataAbilityPredicatesProxy::And(napi_env env, napi_callback_info info napi_value DataAbilityPredicatesProxy::Contains(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -276,7 +276,7 @@ napi_value DataAbilityPredicatesProxy::Contains(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::BeginsWith(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -293,7 +293,7 @@ napi_value DataAbilityPredicatesProxy::BeginsWith(napi_env env, napi_callback_in napi_value DataAbilityPredicatesProxy::EndsWith(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -310,7 +310,7 @@ napi_value DataAbilityPredicatesProxy::EndsWith(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::IsNull(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -325,7 +325,7 @@ napi_value DataAbilityPredicatesProxy::IsNull(napi_env env, napi_callback_info i napi_value DataAbilityPredicatesProxy::IsNotNull(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -340,7 +340,7 @@ napi_value DataAbilityPredicatesProxy::IsNotNull(napi_env env, napi_callback_inf napi_value DataAbilityPredicatesProxy::Like(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -357,7 +357,7 @@ napi_value DataAbilityPredicatesProxy::Like(napi_env env, napi_callback_info inf napi_value DataAbilityPredicatesProxy::Glob(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -374,7 +374,7 @@ napi_value DataAbilityPredicatesProxy::Glob(napi_env env, napi_callback_info inf napi_value DataAbilityPredicatesProxy::Between(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 3; // 3 represents the number of parameters napi_value args[3] = { 0 }; @@ -397,7 +397,7 @@ napi_value DataAbilityPredicatesProxy::Between(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::NotBetween(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 3; // 3 represents the number of parameters napi_value args[3] = { 0 }; @@ -420,7 +420,7 @@ napi_value DataAbilityPredicatesProxy::NotBetween(napi_env env, napi_callback_in napi_value DataAbilityPredicatesProxy::GreaterThan(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -437,7 +437,7 @@ napi_value DataAbilityPredicatesProxy::GreaterThan(napi_env env, napi_callback_i napi_value DataAbilityPredicatesProxy::LessThan(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -454,7 +454,7 @@ napi_value DataAbilityPredicatesProxy::LessThan(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::GreaterThanOrEqualTo(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -471,7 +471,7 @@ napi_value DataAbilityPredicatesProxy::GreaterThanOrEqualTo(napi_env env, napi_c napi_value DataAbilityPredicatesProxy::LessThanOrEqualTo(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -488,7 +488,7 @@ napi_value DataAbilityPredicatesProxy::LessThanOrEqualTo(napi_env env, napi_call napi_value DataAbilityPredicatesProxy::OrderByAsc(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -505,7 +505,7 @@ napi_value DataAbilityPredicatesProxy::OrderByAsc(napi_env env, napi_callback_in napi_value DataAbilityPredicatesProxy::OrderByDesc(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -522,7 +522,7 @@ napi_value DataAbilityPredicatesProxy::OrderByDesc(napi_env env, napi_callback_i napi_value DataAbilityPredicatesProxy::Distinct(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); auto nativePredicates = GetNativePredicates(env, info); RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); @@ -532,7 +532,7 @@ napi_value DataAbilityPredicatesProxy::Distinct(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::Limit(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -549,7 +549,7 @@ napi_value DataAbilityPredicatesProxy::Limit(napi_env env, napi_callback_info in napi_value DataAbilityPredicatesProxy::Offset(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -566,7 +566,7 @@ napi_value DataAbilityPredicatesProxy::Offset(napi_env env, napi_callback_info i napi_value DataAbilityPredicatesProxy::GroupBy(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -583,7 +583,7 @@ napi_value DataAbilityPredicatesProxy::GroupBy(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::IndexedBy(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -600,7 +600,7 @@ napi_value DataAbilityPredicatesProxy::IndexedBy(napi_env env, napi_callback_inf napi_value DataAbilityPredicatesProxy::In(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -620,7 +620,7 @@ napi_value DataAbilityPredicatesProxy::In(napi_env env, napi_callback_info info) napi_value DataAbilityPredicatesProxy::NotIn(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 2; napi_value args[2] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -673,7 +673,7 @@ napi_value DataAbilityPredicatesProxy::GetWhereClause(napi_env env, napi_callbac napi_value DataAbilityPredicatesProxy::SetWhereClause(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -699,7 +699,7 @@ napi_value DataAbilityPredicatesProxy::GetWhereArgs(napi_env env, napi_callback_ napi_value DataAbilityPredicatesProxy::SetWhereArgs(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -725,7 +725,7 @@ napi_value DataAbilityPredicatesProxy::GetOrder(napi_env env, napi_callback_info napi_value DataAbilityPredicatesProxy::SetOrder(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); diff --git a/relational_store/frameworks/js/napi/dataability/src/napi_predicates_utils.cpp b/relational_store/frameworks/js/napi/dataability/src/napi_predicates_utils.cpp index b6461a1888bb0280faf4f0a0391fa56b171ef84b..cf21363cd77699549a24b5ce67da05c944f1e863 100644 --- a/relational_store/frameworks/js/napi/dataability/src/napi_predicates_utils.cpp +++ b/relational_store/frameworks/js/napi/dataability/src/napi_predicates_utils.cpp @@ -30,12 +30,12 @@ napi_value CreateRdbPredicates(napi_env env, napi_callback_info info) { size_t argc = 2; napi_value args[2] = { 0 }; - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thiz, nullptr)); NAPI_ASSERT(env, argc == 2, "DataAbilityJsKit::CreateRdbPredicates Invalid argvs!"); LOG_DEBUG("DataAbilityJsKit::CreateRdbPredicates argc is %{public}zu", argc); - napi_valuetype valueType; + napi_valuetype valueType = napi_undefined; NAPI_CALL(env, napi_typeof(env, args[0], &valueType)); NAPI_ASSERT(env, valueType == napi_string, "Table name should be a string."); std::string tableName = JSUtils::Convert2String(env, args[0]); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp index 916d2d5d38bc511159fdae7a3a8e7cc99232a3e4..5d63128eb3bc5bcf248380385f82ed124756e862 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp @@ -157,7 +157,7 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) // callback napi_value callback = nullptr; napi_get_reference_value(env, context->callback_, &callback); - napi_value returnValue; + napi_value returnValue = nullptr; napi_call_function(env, nullptr, callback, ARG_BUTT, result, &returnValue); } context->keep_.reset(); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_js_utils.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_js_utils.cpp index b8c3e809c1e1942e6c528d05533e02356b458a1c..66f3054842a55b98f8825079001da750cc55b3f0 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_js_utils.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_js_utils.cpp @@ -26,7 +26,7 @@ using namespace NativeRdb; template<> int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); if (status != napi_ok || type != napi_object) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -47,7 +47,7 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output) template<> napi_value Convert2JSValue(napi_env env, const Asset &value) { - napi_value object; + napi_value object = nullptr; NAPI_CALL_BASE(env, napi_create_object(env, &object), object); NAPI_CALL_BASE(env, ADD_JS_PROPERTY(env, object, value, version), object); NAPI_CALL_BASE(env, ADD_JS_PROPERTY(env, object, value, name), object); @@ -62,7 +62,7 @@ napi_value Convert2JSValue(napi_env env, const Asset &value) template<> napi_value Convert2JSValue(napi_env env, const RowEntity &rowEntity) { - napi_value ret; + napi_value ret = nullptr; NAPI_CALL(env, napi_create_object(env, &ret)); auto &values = rowEntity.Get(); for (auto const &[key, object] : values) { diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp index 4083bba0d89612044de9a03ae47f3e89504c8b8c..25cb4b37d9a5632713dc4bd1e4b32e74bab72dd8 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp @@ -84,7 +84,7 @@ void RdbPredicatesProxy::Init(napi_env env, napi_value exports) #endif }; - napi_value cons; + napi_value cons = nullptr; NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "RdbPredicates", NAPI_AUTO_LENGTH, New, nullptr, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons)); NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructor_)); @@ -92,7 +92,7 @@ void RdbPredicatesProxy::Init(napi_env env, napi_value exports) SetGlobalNamedProperty(env, "RdbPredicatesConstructor", cons); - napi_value consV9; + napi_value consV9 = nullptr; NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "RdbPredicatesV9", NAPI_AUTO_LENGTH, NewV9, nullptr, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &consV9)); NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, consV9, 1, &constructor_)); @@ -113,17 +113,17 @@ napi_value RdbPredicatesProxy::NewV9(napi_env env, napi_callback_info info) napi_value RdbPredicatesProxy::InnerNew(napi_env env, napi_callback_info info, int version) { - napi_value new_target; + napi_value new_target = nullptr; NAPI_CALL(env, napi_get_new_target(env, info, &new_target)); bool is_constructor = (new_target != nullptr); size_t argc = 1; napi_value args[1] = { 0 }; - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thiz, nullptr)); if (is_constructor) { - napi_valuetype valueType; + napi_valuetype valueType = napi_undefined; NAPI_CALL(env, napi_typeof(env, args[0], &valueType)); RDB_NAPI_ASSERT_FROMV9( env, valueType == napi_string, std::make_shared("name", "a non empty string."), version); @@ -147,17 +147,17 @@ napi_value RdbPredicatesProxy::InnerNew(napi_env env, napi_callback_info info, i argc = 1; napi_value argv[1] = { args[0] }; - napi_value cons; + napi_value cons = nullptr; NAPI_CALL(env, napi_get_reference_value(env, constructor_, &cons)); - napi_value output; + napi_value output = nullptr; NAPI_CALL(env, napi_new_instance(env, cons, argc, argv, &output)); return output; } napi_value RdbPredicatesProxy::NewInstance(napi_env env, std::shared_ptr value, int version) { - napi_value cons; + napi_value cons = nullptr; napi_status status = napi_get_reference_value(env, constructor_, &cons); if (status != napi_ok) { LOG_ERROR("RdbPredicatesProxy::NewInstance get constructor failed! napi_status:%{public}d!", status); @@ -203,7 +203,7 @@ RdbPredicatesProxy::RdbPredicatesProxy(std::string &tableName) std::shared_ptr RdbPredicatesProxy::GetNativePredicates(napi_env env, napi_callback_info info) { RdbPredicatesProxy *predicatesProxy = nullptr; - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); napi_unwrap(env, thiz, reinterpret_cast(&predicatesProxy)); return predicatesProxy->predicates_; @@ -765,7 +765,7 @@ napi_value RdbPredicatesProxy::GetJoinCount(napi_env env, napi_callback_info inf napi_value RdbPredicatesProxy::SetJoinCount(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; int32_t joinCount = 0; RdbPredicatesProxy *predicatesProxy = ParseInt32FieldByName(env, info, thiz, joinCount, "joinCount"); RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp index 9fba87741aa8209cf73d1dae9586d01626a4cd66..53e7bc64cc8ebba3d5467e6c9bb6077d323555b3 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp @@ -151,7 +151,7 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) napi_value RdbStoreProxy::InnerInitialize(napi_env env, napi_callback_info info, int version) { - napi_value self; + napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, &self, nullptr)); auto finalize = [](napi_env env, void *data, void *hint) { RdbStoreProxy *proxy = reinterpret_cast(data); @@ -187,7 +187,7 @@ napi_value RdbStoreProxy::NewInstance(napi_env env, std::shared_ptr APIVERSION_8) { status = napi_get_reference_value(env, constructorV9_, &cons); @@ -268,9 +268,9 @@ int ParseTablesName(const napi_env env, const napi_value arg, std::shared_ptr= 0, context->SetError(paramError)); for (uint32_t i = 0; i < arrLen; ++i) { - napi_value element; + napi_value element = nullptr; napi_get_element(env, arg, i, &element); - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, element, &type); if (type == napi_string) { std::string table = JSUtils::Convert2String(env, element); @@ -357,7 +357,7 @@ int ParseSrcName(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, arg, &type); if (type == napi_undefined || type == napi_null) { return OK; @@ -400,7 +400,7 @@ int ParsePath(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, arg, &type); if (type == napi_undefined || type == napi_null) { return OK; @@ -413,7 +413,7 @@ int ParseWhereArgs(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, arg, &type); if (type == napi_undefined || type == napi_null) { return OK; @@ -436,7 +436,7 @@ int ParseSql(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_value keys = 0; + napi_value keys = nullptr; napi_get_all_property_names(env, arg, napi_key_own_only, static_cast(napi_key_enumerable | napi_key_skip_symbols), napi_key_numbers_to_strings, &keys); @@ -446,7 +446,7 @@ int ParseValuesBucket(const napi_env env, const napi_value arg, std::shared_ptr< RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok, context->SetError(paramError)); for (size_t i = 0; i < arrLen; ++i) { - napi_value key; + napi_value key = nullptr; status = napi_get_element(env, keys, i, &key); if (status != napi_ok) { LOG_DEBUG("ValuesBucket get_element errr"); @@ -454,7 +454,7 @@ int ParseValuesBucket(const napi_env env, const napi_value arg, std::shared_ptr< RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok, context->SetError(paramError)); std::string keyStr = JSUtils::Convert2String(env, key); - napi_value value; + napi_value value = nullptr; napi_get_property(env, arg, key, &value); ValueObject valueObject; @@ -505,7 +505,7 @@ bool IsNapiString(napi_env env, napi_callback_info info) if (argc < MIN_ARGC) { return false; } - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, args[0], &type); if (type == napi_string) { return true; @@ -763,7 +763,7 @@ int ParseBindArgs(const napi_env env, const napi_value arg, std::shared_ptr int { - napi_value self; + napi_value self = nullptr; napi_status status = napi_get_reference_value(env_, ref_, &self); if (status != napi_ok) { LOG_ERROR("OnCreate get self reference failed, code:%{public}d", status); return E_ERROR; } - napi_value method; + napi_value method = nullptr; status = napi_get_reference_value(env_, onCreate_, &method); if (status != napi_ok) { LOG_ERROR("OnCreate get method reference failed, code:%{public}d", status); @@ -132,13 +132,13 @@ public: { LOG_DEBUG("OnUpgrade Callback"); callbacks_.emplace_back([this, oldVersion, newVersion]() -> int { - napi_value self; + napi_value self = nullptr; napi_status status = napi_get_reference_value(env_, ref_, &self); if (status != napi_ok) { LOG_ERROR("OnUpgrade get self reference failed, code:%{public}d", status); return E_ERROR; } - napi_value method; + napi_value method = nullptr; status = napi_get_reference_value(env_, onUpgrade_, &method); if (status != napi_ok) { LOG_ERROR("OnUpgrade get method reference failed, code:%{public}d", status); @@ -147,7 +147,7 @@ public: napi_value result[JSUtils::ASYNC_RST_SIZE] = { 0 }; napi_get_undefined(env_, &result[0]); napi_create_object(env_, &result[1]); - napi_value version; + napi_value version = nullptr; napi_create_int32(env_, newVersion, &version); napi_set_named_property(env_, result[1], "currentVersion", version); napi_create_int32(env_, oldVersion, &version); @@ -167,13 +167,13 @@ public: { LOG_DEBUG("OnDowngrade Callback"); callbacks_.emplace_back([this, oldVersion, newVersion]() -> int { - napi_value self; + napi_value self = nullptr; napi_status status = napi_get_reference_value(env_, ref_, &self); if (status != napi_ok) { LOG_ERROR("OnDowngrade get self reference failed, code:%{public}d", status); return E_ERROR; } - napi_value method; + napi_value method = nullptr; status = napi_get_reference_value(env_, onDowngrade_, &method); if (status != napi_ok) { LOG_ERROR("OnDowngrade get method reference failed, code:%{public}d", status); @@ -182,7 +182,7 @@ public: napi_value result[JSUtils::ASYNC_RST_SIZE] = { 0 }; napi_get_undefined(env_, &result[0]); napi_create_object(env_, &result[1]); - napi_value version; + napi_value version = nullptr; napi_create_int32(env_, newVersion, &version); napi_set_named_property(env_, result[1], "currentVersion", version); napi_create_int32(env_, oldVersion, &version); @@ -202,13 +202,13 @@ public: { LOG_DEBUG("OnOpen Callback"); callbacks_.emplace_back([this]() -> int { - napi_value self; + napi_value self = nullptr; napi_status status = napi_get_reference_value(env_, ref_, &self); if (status != napi_ok) { LOG_ERROR("OnOpen get self reference failed, code:%{public}d", status); return E_ERROR; } - napi_value method; + napi_value method = nullptr; status = napi_get_reference_value(env_, onOpen_, &method); if (status != napi_ok) { LOG_ERROR("OnOpen get method reference failed, code:%{public}d", status); @@ -275,7 +275,7 @@ int ParseContext(const napi_env &env, const napi_value &object, std::shared_ptr< int ParseDatabaseName(const napi_env &env, const napi_value &object, std::shared_ptr context) { - napi_value value; + napi_value value = nullptr; napi_get_named_property(env, object, "name", &value); std::shared_ptr paramError = std::make_shared("config", "a StoreConfig."); RDB_CHECK_RETURN_CALL_RESULT(value != nullptr, context->SetError(paramError)); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp index 1284f609d189636a9e9fe0bc7c0cef1dadd65893..85cc35396e512929bcee106f9b11e439fa4e6f8c 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp @@ -67,7 +67,7 @@ napi_value ResultSetProxy::NewInstance(napi_env env, std::shared_ptr ResultSetProxy::Create() napi_value ResultSetProxy::GetConstructor(napi_env env, int version) { - napi_value cons; + napi_value cons = nullptr; if (version > APIVERSION_8 && ctorRefV9_ != nullptr) { NAPI_CALL(env, napi_get_reference_value(env, ctorRefV9_, &cons)); return cons; @@ -575,7 +575,7 @@ napi_value ResultSetProxy::IsColumnNull(napi_env env, napi_callback_info info) int errCode = resultSetProxy->resultSet_->IsColumnNull(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); - napi_value output; + napi_value output = nullptr; napi_get_boolean(env, result, &output); return output; } @@ -587,14 +587,14 @@ napi_value ResultSetProxy::IsClosed(napi_env env, napi_callback_info info) RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); int result = resultSetProxy->resultSet_->IsClosed(); - napi_value output; + napi_value output = nullptr; napi_get_boolean(env, result, &output); return output; } napi_value ResultSetProxy::GetSharedBlockName(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); ResultSetProxy *proxy; @@ -607,7 +607,7 @@ napi_value ResultSetProxy::GetSharedBlockName(napi_env env, napi_callback_info i napi_value ResultSetProxy::GetSharedBlockAshmemFd(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); ResultSetProxy *proxy; diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_uv_queue.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_uv_queue.cpp index 442cd6106bd59fe7f3c64a2b9819d23ebe9e892d..2b31f06ef0c7929346a764ccb053901d2fb94293 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_uv_queue.cpp @@ -69,7 +69,7 @@ void NapiUvQueue::CallFunction(NapiArgsGenerator genArgs) napi_get_reference_value(queue->env_, queue->callback_, &callback); napi_value global = nullptr; napi_get_global(queue->env_, &global); - napi_value result; + napi_value result = nullptr; napi_status status = napi_call_function(queue->env_, global, callback, argc, argv, &result); if (status != napi_ok) { LOG_ERROR("napi_call_function failed, status=%{public}d", status); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp index 00349fc66dd3f9f7430cdc75d6b5a446dd9a6b7a..802812bef958c641e47fe529fb09acf20f26b607 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_values_bucket.cpp @@ -26,7 +26,7 @@ using namespace OHOS::NativeRdb; __attribute__((visibility("default"))) napi_value NAPI_OHOS_Data_RdbJsKit_ValuesBucketProxy_NewInstance( napi_env env, ValuesBucket &valuesBucket) { - napi_value ret; + napi_value ret = nullptr; NAPI_CALL(env, napi_create_object(env, &ret)); for (auto &[key, value]: valuesBucket.values_) { napi_value jsValue = JSUtils::Convert2JSValue(env, value.value); @@ -44,7 +44,7 @@ __attribute__((visibility("default"))) ValuesBucket *NAPI_OHOS_Data_RdbJsKit_Val LOG_ERROR("ValuesBucket new failed, valuesBucket is nullptr"); return nullptr; } - napi_value keys = 0; + napi_value keys = nullptr; napi_get_property_names(env, arg, &keys); uint32_t arrLen = 0; napi_status status = napi_get_array_length(env, keys, &arrLen); @@ -53,10 +53,10 @@ __attribute__((visibility("default"))) ValuesBucket *NAPI_OHOS_Data_RdbJsKit_Val return valuesBucket; } for (size_t i = 0; i < arrLen; ++i) { - napi_value key; + napi_value key = nullptr; napi_get_element(env, keys, i, &key); std::string keyStr = JSUtils::Convert2String(env, key); - napi_value value; + napi_value value = nullptr; napi_get_property(env, arg, key, &value); napi_valuetype valueType = napi_undefined; napi_typeof(env, value, &valueType); diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h index b9b8408d84bfa405f12662182589da17b593e250..7ced61d051c0f34e5864cbc2182f00ee98922057 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h @@ -76,8 +76,7 @@ private: static napi_value OffEvent(napi_env env, napi_callback_info info); static napi_value Notify(napi_env env, napi_callback_info info); - static constexpr int MIN_ON_EVENT_ARG_NUM = 2; - static constexpr int MAX_ON_EVENT_ARG_NUM = 5; + static constexpr int EVENT_HANDLE_NUM = 2; napi_value OnRemote(napi_env env, size_t argc, napi_value *argv); napi_value OnLocal(napi_env env, const DistributedRdb::SubscribeOption &option, napi_value callback); @@ -89,12 +88,43 @@ private: napi_value UnRegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, std::map>> &observers, napi_value callback); - std::mutex mutex_; + class SyncObserver + : public DistributedRdb::DetailProgressObserver, public std::enable_shared_from_this { + public: + SyncObserver(napi_env env, napi_value callback, std::shared_ptr uvQueue); + virtual ~SyncObserver(); + bool operator==(napi_value value); + void ProgressNotification(const DistributedRdb::Details &details) override; + + private: + napi_env env_ = nullptr; + napi_ref callback_ = nullptr; + std::shared_ptr queue_ = nullptr; + }; + + napi_value RegisterSyncCallback(napi_env env, size_t argc, napi_value *argv); + napi_value UnregisterSyncCallback(napi_env env, size_t argc, napi_value *argv); + + using EventHandle = napi_value (RdbStoreProxy::*)(napi_env, size_t, napi_value *); + struct HandleInfo { + std::string_view event; + EventHandle handle; + }; + static constexpr HandleInfo onEventHandlers_[EVENT_HANDLE_NUM] = { + { "dataChange", &RdbStoreProxy::OnRemote }, + { "autoSyncProgress", &RdbStoreProxy::RegisterSyncCallback } + }; + static constexpr HandleInfo offEventHandlers_[EVENT_HANDLE_NUM] = { + { "dataChange", &RdbStoreProxy::OffRemote }, + { "autoSyncProgress", &RdbStoreProxy::UnregisterSyncCallback } + }; + bool isSystemAppCalled_ = false; std::shared_ptr queue_; std::list> observers_[DistributedRdb::SUBSCRIBE_MODE_MAX]; std::map>> localObservers_; std::map>> localSharedObservers_; + std::list> syncObservers_; }; } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h deleted file mode 100644 index c4867578f22a68b28cca28bc44e7f27e5007eee2..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2022 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 RDB_JSKIT_NAPI_RDB_PREDICATES_H -#define RDB_JSKIT_NAPI_RDB_PREDICATES_H - -#include - -#include "innerkits/napi/ace_napi/include/napi/native_api.h" -#include "innerkits/napi/ace_napi/include/napi/native_common.h" -#include "innerkits/napi/ace_napi/include/napi/native_node_api.h" -#include "napi_rdb_error.h" -#include "rdb_predicates.h" - -namespace OHOS { -namespace RelationalStoreJsKit { -class RdbPredicatesProxy { -public: - static void Init(napi_env env, napi_value exports); - static napi_value NewInstance(napi_env env, std::shared_ptr value); - static void Destructor(napi_env env, void *nativeObject, void *finalize_hint); - - explicit RdbPredicatesProxy(std::string &tableName); - std::shared_ptr GetPredicates() const; - -private: - ~RdbPredicatesProxy(); - - static napi_value New(napi_env env, napi_callback_info info); - static RdbPredicatesProxy *GetNativePredicates(napi_env env, napi_callback_info info); - - static RdbPredicatesProxy *ParseFieldArrayByName(napi_env env, napi_callback_info info, napi_value &thiz, - std::vector &fieldarray, const std::string fieldName, const std::string fieldType); - static RdbPredicatesProxy *ParseFieldByName( - napi_env env, napi_callback_info info, napi_value &thiz, std::string &field, const std::string fieldName); - static RdbPredicatesProxy *ParseInt32FieldByName( - napi_env env, napi_callback_info info, napi_value &thiz, int32_t &field, const std::string fieldName); - static RdbPredicatesProxy *ParseFieldAndValueArray(napi_env env, napi_callback_info info, napi_value &thiz, - std::string &field, std::vector &value, const std::string valueType); - static RdbPredicatesProxy *ParseFieldAndValue(napi_env env, napi_callback_info info, napi_value &thiz, - std::string &field, NativeRdb::ValueObject &value, const std::string valueType); - static RdbPredicatesProxy *ParseFieldAndStringValue(napi_env env, napi_callback_info info, napi_value &thiz, - std::string &field, std::string &value, const std::string valueType); - static RdbPredicatesProxy *ParseFieldLowAndHigh(napi_env env, napi_callback_info info, napi_value &thiz, - std::string &field, NativeRdb::ValueObject &low, NativeRdb::ValueObject &High); - - static napi_value EqualTo(napi_env env, napi_callback_info info); - static napi_value NotEqualTo(napi_env env, napi_callback_info info); - static napi_value BeginWrap(napi_env env, napi_callback_info info); - static napi_value EndWrap(napi_env env, napi_callback_info info); - static napi_value Or(napi_env env, napi_callback_info info); - static napi_value And(napi_env env, napi_callback_info info); - static napi_value Contains(napi_env env, napi_callback_info info); - static napi_value BeginsWith(napi_env env, napi_callback_info info); - static napi_value EndsWith(napi_env env, napi_callback_info info); - static napi_value IsNull(napi_env env, napi_callback_info info); - static napi_value IsNotNull(napi_env env, napi_callback_info info); - static napi_value Like(napi_env env, napi_callback_info info); - static napi_value Glob(napi_env env, napi_callback_info info); - static napi_value Between(napi_env env, napi_callback_info info); - static napi_value NotBetween(napi_env env, napi_callback_info info); - static napi_value GreaterThan(napi_env env, napi_callback_info info); - static napi_value LessThan(napi_env env, napi_callback_info info); - static napi_value GreaterThanOrEqualTo(napi_env env, napi_callback_info info); - static napi_value LessThanOrEqualTo(napi_env env, napi_callback_info info); - static napi_value OrderByAsc(napi_env env, napi_callback_info info); - static napi_value OrderByDesc(napi_env env, napi_callback_info info); - static napi_value Distinct(napi_env env, napi_callback_info info); - static napi_value Limit(napi_env env, napi_callback_info info); - static napi_value Offset(napi_env env, napi_callback_info info); - static napi_value GroupBy(napi_env env, napi_callback_info info); - static napi_value IndexedBy(napi_env env, napi_callback_info info); - static napi_value In(napi_env env, napi_callback_info info); - static napi_value NotIn(napi_env env, napi_callback_info info); - static napi_value Using(napi_env env, napi_callback_info info); - static napi_value Clear(napi_env env, napi_callback_info info); - static napi_value CrossJoin(napi_env env, napi_callback_info info); - static napi_value LeftOuterJoin(napi_env env, napi_callback_info info); - static napi_value GetJoinCount(napi_env env, napi_callback_info info); - static napi_value SetJoinConditions(napi_env env, napi_callback_info info); - static napi_value SetJoinTableNames(napi_env env, napi_callback_info info); - static napi_value SetJoinTypes(napi_env env, napi_callback_info info); - static napi_value SetJoinCount(napi_env env, napi_callback_info info); - static napi_value GetJoinTypes(napi_env env, napi_callback_info info); - static napi_value GetJoinTableNames(napi_env env, napi_callback_info info); - static napi_value GetJoinConditions(napi_env env, napi_callback_info info); - static napi_value InnerJoin(napi_env env, napi_callback_info info); - static napi_value On(napi_env env, napi_callback_info info); - static napi_value GetStatement(napi_env env, napi_callback_info info); - static napi_value GetBindArgs(napi_env env, napi_callback_info info); - - std::shared_ptr predicates_; -}; -} // namespace RelationalStoreJsKit -} // namespace OHOS - -#endif // RDB_JSKIT_NAPI_RDB_PREDICATES_H diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp index 2b3984f9eab2db8292378f8c126e7df17858d467..54bb9e62a3d12dcfaaea607a4bc44e655759d135 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp @@ -199,7 +199,7 @@ void AsyncCall::OnReturn(napi_env env, napi_status status, void *data) // callback napi_value callback = nullptr; napi_get_reference_value(env, context->callback_, &callback); - napi_value returnValue; + napi_value returnValue = nullptr; napi_call_function(env, nullptr, callback, ARG_BUTT, result, &returnValue); } context->keep_.reset(); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp index 8caba162b4a87b8f6c271c0260af7f1d5b489488..56ed115685a4d8226a2b2c9b2aa52fb41c6d22d9 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp @@ -33,7 +33,7 @@ using namespace NativeRdb; template<> int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, jsValue, &type); bool isArray; napi_status status_array = napi_is_array(env, jsValue, &isArray); @@ -62,7 +62,7 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output) template<> int32_t Convert2Value(napi_env env, napi_value input, DistributedRdb::DistributedConfig &output) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, input, &type); if (status != napi_ok || type != napi_object) { LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); @@ -89,7 +89,7 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, ValueObject &valueObject template<> napi_value Convert2JSValue(napi_env env, const Asset &value) { - napi_value object; + napi_value object = nullptr; NAPI_CALL_RETURN_ERR(napi_create_object(env, &object), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, name), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, uri), object); @@ -104,7 +104,7 @@ napi_value Convert2JSValue(napi_env env, const Asset &value) template<> napi_value Convert2JSValue(napi_env env, const RowEntity &rowEntity) { - napi_value ret; + napi_value ret = nullptr; NAPI_CALL(env, napi_create_object(env, &ret)); auto &values = rowEntity.Get(); for (auto const &[key, object] : values) { @@ -123,7 +123,7 @@ napi_value Convert2JSValue(napi_env env, const ValueObject &valueObject) template<> napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statistic) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_object(env, &jsValue); if (status != napi_ok) { return nullptr; @@ -144,7 +144,7 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statis template<> napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &tableDetail) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_object(env, &jsValue); if (status != napi_ok) { return nullptr; @@ -159,7 +159,7 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &tabl template<> napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tableDetails) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_array_with_length(env, tableDetails.size(), &jsValue); if (status != napi_ok) { return nullptr; @@ -167,7 +167,7 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tab int index = 0; for (const auto &[device, result] : tableDetails) { - napi_value jsElement; + napi_value jsElement = nullptr; status = napi_create_array_with_length(env, 2, &jsElement); if (status != napi_ok) { return nullptr; @@ -182,7 +182,7 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tab template<> napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &progressDetail) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_object(env, &jsValue); if (status != napi_ok) { return nullptr; @@ -208,7 +208,7 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details) template<> napi_value Convert2JSValue(napi_env env, const JSChangeInfo &value) { - napi_value object; + napi_value object = nullptr; auto status = napi_create_object(env, &object); if (status != napi_ok) { return nullptr; @@ -224,7 +224,7 @@ napi_value Convert2JSValue(napi_env env, const JSChangeInfo &value) template<> napi_value Convert2JSValue(napi_env env, const Date &date) { - napi_value jsValue; + napi_value jsValue = nullptr; napi_status status = napi_create_date(env, date, &jsValue); if (status != napi_ok) { return nullptr; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp index e1ee53f56bb83d5f427f26708b360e0050408fb1..f31cf1f10fe7b31f433e4439a0488a603ce3c3b5 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp @@ -76,7 +76,7 @@ void RdbPredicatesProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("inAllDevices", InAllDevices), }; - napi_value cons; + napi_value cons = nullptr; NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "RdbPredicates", NAPI_AUTO_LENGTH, New, nullptr, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons)); NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructor_)); @@ -88,17 +88,17 @@ void RdbPredicatesProxy::Init(napi_env env, napi_value exports) napi_value RdbPredicatesProxy::New(napi_env env, napi_callback_info info) { LOG_DEBUG("RdbPredicatesProxy::New begin."); - napi_value new_target; + napi_value new_target = nullptr; NAPI_CALL(env, napi_get_new_target(env, info, &new_target)); bool is_constructor = (new_target != nullptr); size_t argc = 1; napi_value args[1] = { 0 }; - napi_value thiz; + napi_value thiz = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thiz, nullptr)); if (is_constructor) { - napi_valuetype valueType; + napi_valuetype valueType = napi_undefined; NAPI_CALL(env, napi_typeof(env, args[0], &valueType)); RDB_NAPI_ASSERT(env, valueType == napi_string, std::make_shared("name", "not empty")); std::string tableName = JSUtils::Convert2String(env, args[0]); @@ -120,10 +120,10 @@ napi_value RdbPredicatesProxy::New(napi_env env, napi_callback_info info) argc = 1; napi_value argv[1] = { args[0] }; - napi_value cons; + napi_value cons = nullptr; NAPI_CALL(env, napi_get_reference_value(env, constructor_, &cons)); - napi_value output; + napi_value output = nullptr; NAPI_CALL(env, napi_new_instance(env, cons, argc, argv, &output)); LOG_DEBUG("RdbPredicatesProxy::New end"); return output; @@ -132,7 +132,7 @@ napi_value RdbPredicatesProxy::New(napi_env env, napi_callback_info info) napi_value RdbPredicatesProxy::NewInstance(napi_env env, std::shared_ptr value) { LOG_DEBUG("RdbPredicatesProxy::NewInstance begin."); - napi_value cons; + napi_value cons = nullptr; napi_status status = napi_get_reference_value(env, constructor_, &cons); if (status != napi_ok) { LOG_ERROR("RdbPredicatesProxy::NewInstance get constructor failed! napi_status:%{public}d!", status); @@ -177,7 +177,7 @@ RdbPredicatesProxy::RdbPredicatesProxy(std::string &tableName) RdbPredicatesProxy *RdbPredicatesProxy::GetNativePredicates(napi_env env, napi_callback_info info) { LOG_DEBUG("RdbPredicatesProxy::GetNativePredicates begin."); - napi_value thiz; + napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); RdbPredicatesProxy *proxy = nullptr; @@ -274,7 +274,7 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldAndValue(napi_env env, napi_ca field = JSUtils::Convert2String(env, args[0]); RDB_NAPI_ASSERT(env, !field.empty(), std::make_shared("field", "not empty")); - + int32_t ret = JSUtils::Convert2Value(env, args[1], value); RDB_NAPI_ASSERT(env, ret == napi_ok, std::make_shared("value", "a " + valueType + " array.")); @@ -315,10 +315,10 @@ RdbPredicatesProxy *RdbPredicatesProxy::ParseFieldLowAndHigh( field = JSUtils::Convert2String(env, args[0]); RDB_NAPI_ASSERT(env, !field.empty(), std::make_shared("field", "not empty")); - + int32_t ret = JSUtils::Convert2Value(env, args[1], low); RDB_NAPI_ASSERT(env, ret == napi_ok, std::make_shared("low", "a valueType.")); - + ret = JSUtils::Convert2Value(env, args[2], high); RDB_NAPI_ASSERT(env, ret == napi_ok, std::make_shared("high", "a valueType.")); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp index f20177040ce9f56bba584681ea1239149b92fce0..f7d96721b02755b95baaa4fcc6402cef5623e14a 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp @@ -109,6 +109,38 @@ RdbStoreProxy::RdbStoreProxy() RdbStoreProxy::~RdbStoreProxy() { LOG_DEBUG("RdbStoreProxy destructor"); +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) + if (rdbStore_ == nullptr) { + return; + } + for (int32_t mode = DistributedRdb::REMOTE; mode < DistributedRdb::LOCAL; mode++) { + for (auto &obs : observers_[mode]) { + if (obs == nullptr) { + continue; + } + rdbStore_->UnSubscribe({ static_cast(mode) }, obs.get()); + } + } + for (const auto &[event, observers] : localObservers_) { + for (const auto &obs : observers) { + if (obs == nullptr) { + continue; + } + rdbStore_->UnSubscribe({ static_cast(DistributedRdb::LOCAL), event }, obs.get()); + } + } + for (const auto &[event, observers] : localSharedObservers_) { + for (const auto &obs : observers) { + if (obs == nullptr) { + continue; + } + rdbStore_->UnSubscribe({ static_cast(DistributedRdb::LOCAL_SHARED), event }, obs.get()); + } + } + for (const auto &obs : syncObservers_) { + rdbStore_->UnregisterAutoSyncCallback(obs); + } +#endif } bool RdbStoreProxy::IsSystemAppCalled() @@ -121,7 +153,7 @@ bool IsNapiTypeString(napi_env env, size_t argc, napi_value *argv, size_t arg) if (arg >= argc) { return false; } - napi_valuetype type; + napi_valuetype type = napi_undefined; NAPI_CALL_BASE(env, napi_typeof(env, argv[arg], &type), false); return type == napi_string; } @@ -182,7 +214,7 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) napi_value RdbStoreProxy::Initialize(napi_env env, napi_callback_info info) { - napi_value self; + napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, &self, nullptr)); auto finalize = [](napi_env env, void *data, void *hint) { RdbStoreProxy *proxy = reinterpret_cast(data); @@ -207,7 +239,7 @@ napi_value RdbStoreProxy::NewInstance(napi_env env, std::shared_ptr context) { - napi_unwrap(env, arg, reinterpret_cast(&context->predicatesProxy)); - CHECK_RETURN_SET(context->predicatesProxy != nullptr, + auto status = napi_unwrap(env, arg, reinterpret_cast(&context->predicatesProxy)); + CHECK_RETURN_SET(status == napi_ok && context->predicatesProxy != nullptr, std::make_shared("predicates", "an RdbPredicates.")); context->tableName = context->predicatesProxy->GetPredicates()->GetTableName(); context->rdbPredicates = context->predicatesProxy->GetPredicates(); @@ -389,7 +421,7 @@ int ParseSrcName(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, arg, &type); if (type == napi_undefined || type == napi_null) { return OK; @@ -416,7 +448,7 @@ int ParsePath(const napi_env env, const napi_value arg, std::shared_ptr context) { context->bindArgs.clear(); - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, arg, &type); if (type == napi_undefined || type == napi_null) { return OK; @@ -429,7 +461,7 @@ int ParseBindArgs(const napi_env env, const napi_value arg, std::shared_ptr("values", "not empty.")); for (size_t i = 0; i < arrLen; ++i) { - napi_value element; + napi_value element = nullptr; napi_get_element(env, arg, i, &element); ValueObject valueObject; int32_t ret = JSUtils::Convert2Value(env, element, valueObject.value); @@ -448,7 +480,7 @@ int ParseSql(const napi_env env, const napi_value arg, std::shared_ptr context) { - napi_value keys = 0; + napi_value keys = nullptr; napi_get_all_property_names(env, arg, napi_key_own_only, static_cast(napi_key_enumerable | napi_key_skip_symbols), napi_key_numbers_to_strings, &keys); @@ -457,11 +489,11 @@ int ParseValuesBucket(const napi_env env, const napi_value arg, std::shared_ptr< CHECK_RETURN_SET(status == napi_ok, std::make_shared("values", "a ValuesBucket.")); for (size_t i = 0; i < arrLen; ++i) { - napi_value key; + napi_value key = nullptr; status = napi_get_element(env, keys, i, &key); CHECK_RETURN_SET(status == napi_ok, std::make_shared("values", "a ValuesBucket.")); std::string keyStr = JSUtils::Convert2String(env, key); - napi_value value; + napi_value value = nullptr; napi_get_property(env, arg, key, &value); ValueObject valueObject; int32_t ret = JSUtils::Convert2Value(env, value, valueObject.value); @@ -989,7 +1021,7 @@ napi_value RdbStoreProxy::GetVersion(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info) { - napi_value thiz; + napi_value thiz = nullptr; size_t argc = 1; napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); @@ -1121,11 +1153,10 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) +InputAction GetCloudSyncInput(std::shared_ptr context) { - LOG_DEBUG("RdbStoreProxy::CloudSync start"); - auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + return [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + // The number of parameters should be between 2 and 4 CHECK_RETURN_SET_E(argc > 1 && argc < 5, std::make_shared("2 - 4")); CHECK_RETURN(OK == ParserThis(env, self, context)); CHECK_RETURN(OK == ParseCloudSyncModeArg(env, argv[0], context)); @@ -1135,6 +1166,14 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) if (isArray) { CHECK_RETURN(OK == ParseTablesName(env, argv[index], context)); index++; + } else { + auto status = napi_unwrap(env, argv[index], reinterpret_cast(&context->predicatesProxy)); + if (status == napi_ok && context->predicatesProxy != nullptr) { + RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_SET_E(obj != nullptr && obj->IsSystemAppCalled(), std::make_shared()); + context->rdbPredicates = context->predicatesProxy->GetPredicates(); + index++; + } } CHECK_RETURN(OK == ParseCloudSyncCallback(env, argv[index++], context)); CHECK_RETURN_SET_E(index == argc - 1 || index == argc, std::make_shared("2 - 4")); @@ -1142,6 +1181,13 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseCallback(env, argv[index], context)); } }; +} + +napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("RdbStoreProxy::CloudSync start"); + auto context = std::make_shared(); + auto input = GetCloudSyncInput(context); auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::CloudSync Async"); auto *obj = reinterpret_cast(context->boundObj); @@ -1149,17 +1195,21 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) option.mode = static_cast(context->syncMode); option.isBlock = false; CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); - context->execCode_ = obj->rdbStore_->Sync(option, context->tablesNames, - [queue = obj->queue_, callback = context->asyncHolder](const Details &details) { - if (queue == nullptr || callback == nullptr) { - return; - } - bool repeat = !details.empty() && details.begin()->second.progress != DistributedRdb::SYNC_FINISH; - queue->AsyncCall({ callback, repeat }, [details](napi_env env, int &argc, napi_value *argv) -> void { - argc = 1; - argv[0] = details.empty() ? nullptr : JSUtils::Convert2JSValue(env, details.begin()->second); - }); + auto aysnc = [queue = obj->queue_, callback = context->asyncHolder](const Details &details) { + if (queue == nullptr || callback == nullptr) { + return; + } + bool repeat = !details.empty() && details.begin()->second.progress != DistributedRdb::SYNC_FINISH; + queue->AsyncCall({ callback, repeat }, [details](napi_env env, int &argc, napi_value *argv) -> void { + argc = 1; + argv[0] = details.empty() ? nullptr : JSUtils::Convert2JSValue(env, details.begin()->second); }); + }; + if (context->rdbPredicates == nullptr) { + context->execCode_ = obj->rdbStore_->Sync(option, context->tablesNames, aysnc); + } else { + context->execCode_ = obj->rdbStore_->Sync(option, *(context->rdbPredicates), aysnc); + } return OK; }; auto output = [context](napi_env env, napi_value &result) { @@ -1205,7 +1255,7 @@ napi_value RdbStoreProxy::GetModifyTime(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) { - napi_valuetype type; + napi_valuetype type = napi_undefined; int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX; napi_get_value_int32(env, argv[0], &mode); bool valid = (mode >= 0 && mode < SubscribeMode::SUBSCRIBE_MODE_MAX); @@ -1214,7 +1264,6 @@ napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) napi_typeof(env, argv[1], &type); RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); - std::lock_guard lockGuard(mutex_); bool result = std::any_of(observers_[mode].begin(), observers_[mode].end(), [argv](const auto &observer) { return *observer == argv[1]; }); @@ -1235,7 +1284,6 @@ napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) napi_value RdbStoreProxy::RegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, std::map>> &observers, napi_value callback) { - std::lock_guard lockGuard(mutex_); observers.try_emplace(option.event); auto &list = observers.find(option.event)->second; bool result = std::any_of(list.begin(), list.end(), [callback](const auto &observer) { @@ -1264,7 +1312,7 @@ napi_value RdbStoreProxy::OnLocal(napi_env env, const DistributedRdb::SubscribeO napi_value RdbStoreProxy::OffRemote(napi_env env, size_t argc, napi_value *argv) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, argv[0], &type); RDB_NAPI_ASSERT(env, type == napi_number, std::make_shared("type", "SubscribeType")); @@ -1281,7 +1329,6 @@ napi_value RdbStoreProxy::OffRemote(napi_env env, size_t argc, napi_value *argv) SubscribeOption option; option.mode = static_cast(mode); - std::lock_guard lockGuard(mutex_); for (auto it = observers_[mode].begin(); it != observers_[mode].end();) { if (*it == nullptr) { it = observers_[mode].erase(it); @@ -1305,7 +1352,6 @@ napi_value RdbStoreProxy::OffRemote(napi_env env, size_t argc, napi_value *argv) napi_value RdbStoreProxy::UnRegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, std::map>> &observers, napi_value callback) { - std::lock_guard lockGuard(mutex_); auto obs = observers.find(option.event); if (obs == observers.end()) { LOG_INFO("observer not found, event: %{public}s", option.event.c_str()); @@ -1347,40 +1393,35 @@ napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) size_t argc = 3; napi_value argv[3]{}; napi_value self = nullptr; - napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); - // 'argc == 3' represents the number of parameters is three - RDB_NAPI_ASSERT(env, status == napi_ok && (argc == 3), std::make_shared("3")); + int32_t status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + // 'argc == 3 || argc == 2' represents the number of parameters is three or two + RDB_NAPI_ASSERT(env, status == napi_ok && (argc == 3 || argc == 2), std::make_shared("2 or 3")); auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); - napi_valuetype type; - napi_typeof(env, argv[1], &type); - if (type == napi_number) { - std::string event = JSUtils::Convert2String(env, argv[0]); - RDB_NAPI_ASSERT(env, event == "dataChange", std::make_shared("event", "dataChange")); - return proxy->OnRemote(env, argc - 1, argv + 1); - } else if (type == napi_boolean) { - bool valueBool = false; - napi_get_value_bool(env, argv[1], &valueBool); - - napi_typeof(env, argv[0], &type); - RDB_NAPI_ASSERT(env, type == napi_string, std::make_shared("event", "string")); - std::string event = JSUtils::Convert2String(env, argv[0]); - RDB_NAPI_ASSERT(env, !event.empty(), std::make_shared("event", "a not empty string.")); - // 'argv[2]' represents a callback function - napi_typeof(env, argv[2], &type); - RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); - SubscribeOption option; - option.event = event; - valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; - // 'argv[2]' represents a callback function - return proxy->OnLocal(env, option, argv[2]); - } else { - RDB_NAPI_ASSERT(env, false, - std::make_shared("type or supportShared ", "SubscribeType or bool")); + std::string event; + // 'argv[0]' represents a event + status = JSUtils::Convert2Value(env, argv[0], event); + RDB_NAPI_ASSERT( + env, status == napi_ok && !event.empty(), std::make_shared("event", "a not empty string.")); + for (auto &eventInfo : onEventHandlers_) { + if (eventInfo.event == event) { + return (proxy->*(eventInfo.handle))(env, argc - 1, argv + 1); + } } - return nullptr; + + bool valueBool = false; + status = JSUtils::Convert2Value(env, argv[1], valueBool); + RDB_NAPI_ASSERT(env, status == napi_ok, std::make_shared("interProcess", "a boolean.")); + napi_valuetype type = napi_undefined; + napi_typeof(env, argv[2], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); + SubscribeOption option; + option.event = event; + valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; + // 'argv[2]' represents a callback function + return proxy->OnLocal(env, option, argv[2]); } napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) @@ -1389,42 +1430,39 @@ napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) // 'argv[3]' represents an array containing three elements napi_value argv[3] = { nullptr }; napi_value self = nullptr; - napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); - // 'argc == 2 || argc == 3' represents the number of parameters is two or three - RDB_NAPI_ASSERT(env, status == napi_ok && (argc == 2 || argc == 3), std::make_shared("2 or 3")); + int32_t status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + // '1 <= argc && argc <= 3' represents the number of parameters is 1 - 3 + RDB_NAPI_ASSERT(env, status == napi_ok && 1 <= argc && argc <= 3, std::make_shared("1 - 3")); auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); - napi_valuetype type; - napi_typeof(env, argv[1], &type); - if (type == napi_number) { - std::string event = JSUtils::Convert2String(env, argv[0]); - RDB_NAPI_ASSERT(env, event == "dataChange", std::make_shared("event", "dataChange")); - return proxy->OffRemote(env, argc - 1, argv + 1); - } else if (type == napi_boolean) { - bool valueBool = false; - napi_get_value_bool(env, argv[1], &valueBool); - - std::string event = JSUtils::Convert2String(env, argv[0]); - RDB_NAPI_ASSERT(env, !event.empty(), std::make_shared("event", "a not empty string.")); - - // 'argc == 3' represents determine whether the value of variable 'argc' is equal to '3' - if (argc == 3) { - // 'argv[2]' represents a callback function - napi_typeof(env, argv[2], &type); - RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); + std::string event; + status = JSUtils::Convert2Value(env, argv[0], event); + RDB_NAPI_ASSERT( + env, status == napi_ok && !event.empty(), std::make_shared("event", "a not empty string.")); + for (auto &eventInfo : offEventHandlers_) { + if (eventInfo.event == event) { + return (proxy->*(eventInfo.handle))(env, argc - 1, argv + 1); } - SubscribeOption option; - option.event = event; - valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; + } + + bool valueBool = false; + status = JSUtils::Convert2Value(env, argv[1], valueBool); + RDB_NAPI_ASSERT(env, status == napi_ok, std::make_shared("interProcess", "a boolean.")); + + // 'argc == 3' represents determine whether the value of variable 'argc' is equal to '3' + if (argc == 3) { // 'argv[2]' represents a callback function - return proxy->OffLocal(env, option, argv[2]); - } else { - RDB_NAPI_ASSERT(env, false, - std::make_shared("type or supportShared ", "SubscribeType or bool")); + napi_valuetype type = napi_undefined; + napi_typeof(env, argv[2], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); } - return nullptr; + SubscribeOption option; + option.event = event; + valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; + // 'argv[2]' represents a callback function + return proxy->OffLocal(env, option, argv[2]); } napi_value RdbStoreProxy::Notify(napi_env env, napi_callback_info info) @@ -1441,6 +1479,85 @@ napi_value RdbStoreProxy::Notify(napi_env env, napi_callback_info info) RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); return nullptr; } + +napi_value RdbStoreProxy::RegisterSyncCallback(napi_env env, size_t argc, napi_value *argv) +{ + napi_valuetype type = napi_undefined; + napi_typeof(env, argv[0], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("progress", "function")); + bool result = std::any_of(syncObservers_.begin(), syncObservers_.end(), [argv](const auto &observer) { + return *observer == argv[1]; + }); + if (result) { + LOG_INFO("duplicate subscribe"); + return nullptr; + } + auto observer = std::make_shared(env, argv[0], queue_); + int errCode = rdbStore_->RegisterAutoSyncCallback(observer); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + syncObservers_.push_back(std::move(observer)); + LOG_INFO("progress subscribe success"); + return nullptr; +} + +napi_value RdbStoreProxy::UnregisterSyncCallback(napi_env env, size_t argc, napi_value *argv) +{ + napi_valuetype type; + bool isNotNull = argc >= 1 && !JSUtils::IsNull(env, argv[0]); + if (isNotNull) { + napi_typeof(env, argv[0], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("progress", "function")); + } + + for (auto it = syncObservers_.begin(); it != syncObservers_.end();) { + if (*it == nullptr) { + it = syncObservers_.erase(it); + continue; + } + if (isNotNull && !(**it == argv[1])) { + ++it; + continue; + } + + int errCode = rdbStore_->UnregisterAutoSyncCallback(*it); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + it = syncObservers_.erase(it); + LOG_INFO("progress unsubscribe success"); + return nullptr; + } + LOG_INFO("observer not found"); + return nullptr; +} + +RdbStoreProxy::SyncObserver::SyncObserver( + napi_env env, napi_value callback, std::shared_ptr queue) + : env_(env), queue_(queue) +{ + napi_create_reference(env, callback, 1, &callback_); +} + +RdbStoreProxy::SyncObserver::~SyncObserver() +{ + if (env_ != nullptr && callback_ != nullptr) { + napi_delete_reference(env_, callback_); + } +} + +bool RdbStoreProxy::SyncObserver::operator==(napi_value value) +{ + return JSUtils::Equal(env_, callback_, value); +} + +void RdbStoreProxy::SyncObserver::ProgressNotification(const Details &details) +{ + if (queue_ != nullptr) { + queue_->AsyncCall({ callback_, true }, + [details, obs = shared_from_this()](napi_env env, int &argc, napi_value *argv) -> void { + argc = 1; + argv[0] = details.empty() ? nullptr : JSUtils::Convert2JSValue(env, details.begin()->second); + }); + } +} #endif } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp index 130b78157db7e667cac99b524a678e95af96c6bd..bec31b1846d2c34038701f5a047e84b4ceed0ff5 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp @@ -51,7 +51,7 @@ struct HelperRdbContext : public Context { int ParseContext(const napi_env &env, const napi_value &object, std::shared_ptr context) { - napi_valuetype type; + napi_valuetype type = napi_undefined; napi_typeof(env, object, &type); CHECK_RETURN_SET(type == napi_object, std::make_shared("context", "object.")); auto abilityContext = JSAbility::GetContext(env, object); @@ -88,10 +88,9 @@ int ParseContextProperty(const napi_env &env, std::shared_ptr return OK; } -int ParseDatabaseDir(const napi_env &env, const napi_value &object, std::shared_ptr context) +int ParseDatabaseName(const napi_env &env, const napi_value &object, std::shared_ptr context) { - int errorCode = E_OK; - napi_value value; + napi_value value = nullptr; napi_get_named_property(env, object, "name", &value); CHECK_RETURN_SET(value != nullptr, std::make_shared("config", "a StoreConfig.")); std::string databaseName = JSUtils::Convert2String(env, value); @@ -100,17 +99,37 @@ int ParseDatabaseDir(const napi_env &env, const napi_value &object, std::shared_ CHECK_RETURN_SET(false, std::make_shared("StoreConfig.name", "a file name without path")); } context->config.SetName(databaseName); + return OK; +} - std::string databaseDir; +int ParseDatabasePath(const napi_env &env, const napi_value &object, std::shared_ptr context) +{ + int errorCode = E_OK; + + std::string defaultDir; if (context->config.GetDataGroupId().empty()) { - databaseDir = context->abilitycontext->GetDatabaseDir(); + defaultDir = context->abilitycontext->GetDatabaseDir(); } else { - errorCode = context->abilitycontext->GetSystemDatabaseDir(context->config.GetDataGroupId(), databaseDir); + errorCode = context->abilitycontext->GetSystemDatabaseDir(context->config.GetDataGroupId(), defaultDir); CHECK_RETURN_SET((errorCode == E_OK), std::make_shared(E_DATA_GROUP_ID_INVALID)); } - std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); - CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("config", "a StoreConfig.")); + bool hasProp = false; + std::string customDir; + napi_status status = napi_has_named_property(env, object, "customDir", &hasProp); + if (status == napi_ok && hasProp) { + napi_value value = nullptr; + napi_get_named_property(env, object, "customDir", &value); + CHECK_RETURN_SET(value != nullptr, std::make_shared("config", "a StoreConfig.")); + JSUtils::Convert2Value(env, value, customDir); + context->config.SetCustomDir(customDir); + } + + auto [realPath, errCode] = RdbSqlUtils::GetDefaultDatabasePath(defaultDir, context->config.GetName(), customDir); + // customDir length is limited to 1024 bytes + CHECK_RETURN_SET(errCode == E_OK && realPath.length() <= 1024, + std::make_shared("config", "a StoreConfig.")); + context->config.SetPath(std::move(realPath)); return OK; } @@ -162,7 +181,8 @@ int ParseStoreConfig(const napi_env &env, const napi_value &object, std::shared_ CHECK_RETURN_CORE(OK == ParseSecurityLevel(env, object, context), RDB_REVT_NOTHING, ERR); CHECK_RETURN_CORE(OK == ParseDataGroupId(env, object, context), RDB_REVT_NOTHING, ERR); CHECK_RETURN_CORE(OK == ParseContextProperty(env, context), RDB_REVT_NOTHING, ERR); - CHECK_RETURN_CORE(OK == ParseDatabaseDir(env, object, context), RDB_REVT_NOTHING, ERR); + CHECK_RETURN_CORE(OK == ParseDatabaseName(env, object, context), RDB_REVT_NOTHING, ERR); + CHECK_RETURN_CORE(OK == ParseDatabasePath(env, object, context), RDB_REVT_NOTHING, ERR); return OK; } @@ -176,10 +196,11 @@ int ParsePath(const napi_env env, const napi_value arg, std::shared_ptrabilitycontext != nullptr, std::make_shared("abilitycontext", "abilitycontext is nullptr")); - std::string databaseDir = context->abilitycontext->GetDatabaseDir(); + std::string defaultDir = context->abilitycontext->GetDatabaseDir(); + int errorCode = E_OK; - std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); - CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("path", "access")); + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(defaultDir, path, errorCode); + CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("config", "a StoreConfig.")); context->config.SetPath(realPath); return OK; @@ -190,7 +211,7 @@ bool IsNapiString(napi_env env, size_t argc, napi_value *argv, size_t arg) if (arg >= argc) { return false; } - napi_valuetype type; + napi_valuetype type = napi_undefined; NAPI_CALL_BASE(env, napi_typeof(env, argv[arg], &type), false); return type == napi_string; } diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp index 0f16b07fdbaf4a7056b22cca689cbfe0d38df912..03f44b4e5b90c286922fe3b0c5b70a047357167f 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp @@ -45,7 +45,7 @@ napi_value ResultSetProxy::NewInstance(napi_env env, std::shared_ptr ResultSetProxy::Create() napi_value ResultSetProxy::GetConstructor(napi_env env) { - napi_value cons; + napi_value cons = nullptr; if (ctorRef_ != nullptr) { NAPI_CALL(env, napi_get_reference_value(env, ctorRef_, &cons)); return cons; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp index 0c7c739ad0bcee7c265b03b3942358593280acf8..f73cf226b9568dbf16194fe459e226c0cf9abc73 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp @@ -72,7 +72,7 @@ void NapiUvQueue::CallFunction(NapiArgsGenerator genArgs) napi_get_reference_value(queue->env_, queue->callback_, &callback); napi_value global = nullptr; napi_get_global(queue->env_, &global); - napi_value result; + napi_value result = nullptr; napi_status status = napi_call_function(queue->env_, global, callback, argc, argv, &result); if (status != napi_ok) { LOG_ERROR("napi_call_function failed, status=%{public}d", status); diff --git a/relational_store/frameworks/native/rdb/include/rdb_notifier_stub.h b/relational_store/frameworks/native/rdb/include/rdb_notifier_stub.h index 35663b0ba0b2757193b295e362e829deb5b8302f..bcfee4a784f2a687a26be3c4c128379b65d7ea00 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_notifier_stub.h +++ b/relational_store/frameworks/native/rdb/include/rdb_notifier_stub.h @@ -29,27 +29,33 @@ public: class RdbNotifierStub : public IRemoteStub { public: using SyncCompleteHandler = std::function; + using AutoSyncCompleteHandler = std::function; using DataChangeHandler = std::function; - RdbNotifierStub(const SyncCompleteHandler&, const DataChangeHandler&); + RdbNotifierStub(const SyncCompleteHandler&, const AutoSyncCompleteHandler&, const DataChangeHandler&); virtual ~RdbNotifierStub() noexcept; int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; int32_t OnComplete(uint32_t seqNum, Details &&result) override; + int32_t OnComplete(const std::string& storeName, Details &&result) override; int32_t OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) override; private: int32_t OnCompleteInner(MessageParcel& data, MessageParcel& reply); + int32_t OnAutoSyncCompleteInner(MessageParcel& data, MessageParcel& reply); int32_t OnChangeInner(MessageParcel& data, MessageParcel& reply); bool CheckInterfaceToken(MessageParcel& data); using RequestHandle = int32_t (RdbNotifierStub::*)(MessageParcel&, MessageParcel&); static constexpr RequestHandle HANDLES[static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_MAX)] = { [static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_SYNC_COMPLETE)] = &RdbNotifierStub::OnCompleteInner, + [static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_AUTO_SYNC_COMPLETE)] = + &RdbNotifierStub::OnAutoSyncCompleteInner, [static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_DATA_CHANGE)] = &RdbNotifierStub::OnChangeInner, }; SyncCompleteHandler completeNotifier_; + AutoSyncCompleteHandler autoSyncCompleteHandler_; DataChangeHandler changeNotifier_; }; } // namespace OHOS::DistributedRdb diff --git a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h index acc1ee9ec3d758c23732c1afa09c1377f950ae6f..9ff2aa4aede5b07853740c334c799f0d394f2a5a 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h +++ b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h @@ -32,7 +32,6 @@ public: SubscribeOption subscribeOption{ SubscribeMode::REMOTE }; }; using Observers = ConcurrentMap>; - explicit RdbServiceProxy(const sptr& object); std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; @@ -52,6 +51,13 @@ public: int32_t UnSubscribe(const RdbSyncerParam& param, const SubscribeOption& option, RdbStoreObserver *observer) override; + + int32_t RegisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) override; + + int32_t UnregisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) override; + int32_t RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet) override; @@ -65,6 +71,8 @@ public: private: using ChangeInfo = RdbStoreObserver::ChangeInfo; using PrimaryFields = RdbStoreObserver::PrimaryFields; + using SyncCallbacks = ConcurrentMap; + using SyncObservers = ConcurrentMap>>; std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates); @@ -79,19 +87,25 @@ private: int32_t DoSubscribe(const RdbSyncerParam& param, const SubscribeOption &option); int32_t DoUnSubscribe(const RdbSyncerParam& param); + + int32_t DoRegister(const RdbSyncerParam ¶m); + + int32_t DoUnRegister(const RdbSyncerParam ¶m); uint32_t GetSeqNum(); void OnSyncComplete(uint32_t seqNum, Details &&result); + void OnSyncComplete(const std::string &storeName, Details &&result); + void OnDataChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo); - std::string RemoveSuffix(const std::string& name); + static std::string RemoveSuffix(const std::string& name); std::atomic seqNum_ {}; - - ConcurrentMap syncCallbacks_; Observers observers_; + SyncCallbacks syncCallbacks_; + SyncObservers syncObservers_; sptr notifier_; sptr remote_; diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h index d77d726fd7967ff57c707da364199c1c75c25c39..e0dcb72bfd34c5b9e08bf3ffd7339b16e3900421 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -25,6 +25,7 @@ #include "dataobs_mgr_client.h" #include "data_ability_observer_stub.h" +#include "rdb_service.h" #include "rdb_store.h" #include "rdb_store_config.h" #include "refbase.h" @@ -156,14 +157,20 @@ public: int Sync(const SyncOption &option, const std::vector &tables, const AsyncDetail &async) override; + int Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async) override; + int Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; + int RegisterAutoSyncCallback(std::shared_ptr observer) override; + + int UnregisterAutoSyncCallback(std::shared_ptr observer) override; + int Notify(const std::string &event) override; - std::map GetModifyTime( - const std::string &table, const std::string &columnName, std::vector &keys) override; + ModifyTime GetModifyTime(const std::string& table, const std::string& columnName, + std::vector& keys) override; private: int InnerOpen(); @@ -177,10 +184,11 @@ private: int ExecuteGetLongInner(const std::string &sql, const std::vector &bindArgs); void SetAssetStatusWhileInsert(const ValueObject &val); void DoCloudSync(const std::string &table); + int InnerSync(const DistributedRdb::RdbService::Option &option, const DistributedRdb::PredicatesMemo &predicates, + const AsyncDetail &async); int InnerBackup(const std::string databasePath, const std::vector destEncryptKey = std::vector()); - std::map GetModifyTimeByRowId( - const std::string &logTable, std::vector &keys); + ModifyTime GetModifyTimeByRowId(const std::string& logTable, std::vector& keys); inline std::string GetSqlArgs(size_t size); Uri GetUri(const std::string &event); int SubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer); diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h index e6cbab51923a1e5d730b9ab52ca7c553f9c1d02a..7f5627d582bb40a5e6db6586407af228c383a1e0 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h @@ -41,6 +41,7 @@ public: private: int ProcessOpenCallback(RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback); + std::string bundleName_; std::mutex mutex_; std::map> storeCache_; }; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/include/sqlite_connection.h index 7419a52819358d1112cc7c0a7296c06ba4c596de..67c0fdc182de9ef15276e2a01f84608948d0d952 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection.h @@ -83,6 +83,8 @@ private: int SetCustomFunctions(const RdbStoreConfig &config); int SetCustomScalarFunction(const std::string &functionName, int argc, ScalarFunction *function); + friend class SqliteStatement; + sqlite3 *dbHandle; bool isWriteConnection; bool isReadOnly; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h index 2b4cf97d29c177cc5891d3e19482ae2baa7b2e80..be54164ff63e37b3ce07625e23f476b7410b8d03 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h @@ -42,7 +42,8 @@ public: #endif int ChangeDbFileForRestore(const std::string newPath, const std::string backupPath, const std::vector &newKey); - std::stack &getTransactionStack(); + std::stack &GetTransactionStack(); + std::mutex &GetTransactionStackMutex(); int AcquireTransaction(); void ReleaseTransaction(); @@ -72,6 +73,7 @@ private: const static int LIMITATION = 1024; std::stack transactionStack; + std::mutex transactionStackMutex; std::condition_variable transCondition; std::mutex transMutex; bool transactionUsed; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_statement.h b/relational_store/frameworks/native/rdb/include/sqlite_statement.h index dcfa00135ab6633731f785b72c0b47635973f488..ba5d04af91d575e4ce59e99268bfc02f536b3a22 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_statement.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_statement.h @@ -16,6 +16,7 @@ #ifndef NATIVE_RDB_SQLITE_STATEMENT_H #define NATIVE_RDB_SQLITE_STATEMENT_H +#include #include #include "sqlite3sym.h" @@ -23,10 +24,13 @@ namespace OHOS { namespace NativeRdb { +class SqliteConnection; + class SqliteStatement { public: SqliteStatement(); ~SqliteStatement(); + static std::shared_ptr CreateStatement(SqliteConnection *connection, const std::string &sql); int Prepare(sqlite3 *dbHandle, const std::string &sql); int Finalize(); int BindArguments(const std::vector &bindArgs) const; @@ -48,6 +52,8 @@ public: return stmtHandle; } + static constexpr int COLUMN_TYPE_ASSET = 1000; + static constexpr int COLUMN_TYPE_ASSETS = 1001; private: using Asset = ValueObject::Asset; using Assets = ValueObject::Assets; diff --git a/relational_store/frameworks/native/rdb/include/step_result_set.h b/relational_store/frameworks/native/rdb/include/step_result_set.h index c0bd917e49f1e6b7a68321d119c0b6def99f7834..bd84ff38e6b795fdc7c7986322920dabe0bb741e 100644 --- a/relational_store/frameworks/native/rdb/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/include/step_result_set.h @@ -76,7 +76,6 @@ private: static const int STEP_QUERY_RETRY_MAX_TIMES = 50; // Interval of retrying step query in millisecond static const int STEP_QUERY_RETRY_INTERVAL = 1000; - SqliteConnection *connection_; std::vector columnNames_; }; } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/mock/include/base_transaction.h b/relational_store/frameworks/native/rdb/mock/include/base_transaction.h deleted file mode 100644 index 11ad2f5b5702835f7fe28281bb91a41e775e1045..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/native/rdb/mock/include/base_transaction.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTEDDATAMGR_APPDATAMGR_BASE_TRANSACTION_H -#define DISTRIBUTEDDATAMGR_APPDATAMGR_BASE_TRANSACTION_H - -#include - -namespace OHOS::NativeRdb { -enum TransType { - ROLLBACK_SELF = 1, - ROLLBACK_PARENT, -}; - -class BaseTransaction { -public: - explicit BaseTransaction(int id); - ~BaseTransaction(); - bool IsAllBeforeSuccessful() const; - void SetAllBeforeSuccessful(bool allBeforeSuccessful); - bool IsMarkedSuccessful() const; - void SetMarkedSuccessful(bool markedSuccessful); - int GetType() const; - bool IsChildFailure() const; - void SetChildFailure(bool failureFlag); - std::string GetTransactionStr(); - std::string GetCommitStr(); - std::string GetRollbackStr(); - -private: - bool allBeforeSuccessful; - bool markedSuccessful; - bool childFailure; - int type; - int id; - - const std::string BEGIN_IMMEDIATE = "BEGIN EXCLUSIVE"; - const std::string TRANS_STR = "TRANS_STR"; - const std::string SAVE_POINT = "SAVEPOINT"; - const std::string COMMIT = "COMMIT"; - const std::string ROLLBACK = "ROLLBACK"; - const std::string ROLLBACK_TO = "ROLLBACK TO"; -}; -} // namespace OHOS::NativeRdb -#endif diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h b/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h index e6cbab51923a1e5d730b9ab52ca7c553f9c1d02a..7f5627d582bb40a5e6db6586407af228c383a1e0 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h +++ b/relational_store/frameworks/native/rdb/mock/include/rdb_store_manager.h @@ -41,6 +41,7 @@ public: private: int ProcessOpenCallback(RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback); + std::string bundleName_; std::mutex mutex_; std::map> storeCache_; }; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h index 68aabdb4c0656b9b740a4d3f54fe45827ef28d35..cdea3b6e5f48236eea211a2c634c2942ce13b491 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h @@ -77,6 +77,8 @@ private: int SetCustomFunctions(const RdbStoreConfig &config); int SetCustomScalarFunction(const std::string &functionName, int argc, ScalarFunction *function); + friend class SqliteStatement; + sqlite3 *dbHandle; bool isWriteConnection; bool isReadOnly; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h index 2b4cf97d29c177cc5891d3e19482ae2baa7b2e80..be54164ff63e37b3ce07625e23f476b7410b8d03 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h @@ -42,7 +42,8 @@ public: #endif int ChangeDbFileForRestore(const std::string newPath, const std::string backupPath, const std::vector &newKey); - std::stack &getTransactionStack(); + std::stack &GetTransactionStack(); + std::mutex &GetTransactionStackMutex(); int AcquireTransaction(); void ReleaseTransaction(); @@ -72,6 +73,7 @@ private: const static int LIMITATION = 1024; std::stack transactionStack; + std::mutex transactionStackMutex; std::condition_variable transCondition; std::mutex transMutex; bool transactionUsed; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_global_config.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_global_config.h deleted file mode 100644 index 404bb3fea8f5348520ae53e8eb85fcf617a40275..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_global_config.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021 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 NATIVE_RDB_SQLITE_GLOBAL_CONFIG_H -#define NATIVE_RDB_SQLITE_GLOBAL_CONFIG_H - -#include - -namespace OHOS { -namespace NativeRdb { - -class GlobalExpr { -public: - static constexpr bool CALLBACK_LOG_SWITCH = true; /* Sqlite callback log switch */ - static constexpr bool DB_AUTO_CHECK = false; /* Sqlite callback log switch */ - static constexpr int SOFT_HEAP_LIMIT = 8 * 1024 * 1024; /* 8MB */ - static constexpr int DB_PAGE_SIZE = 4096; /* default page size : 4k */ - static constexpr int DB_JOURNAL_SIZE = 1024 * 1024; /* default file size : 1M */ - static constexpr int DB_WAL_SIZE_LIMIT = 200 * 1024 * 1024; /* default wal file maximum size : 200M */ - static constexpr int WAL_AUTO_CHECKPOINT = 100; /* 100 pages */ - static constexpr int APP_DEFAULT_UMASK = 0002; - static constexpr int SQLITE_MAX_COLUMN = 2000; - static constexpr char ATTACH_BACKUP_SQL[] = "ATTACH ? AS backup KEY ?"; - static constexpr char ATTACH_SQL[] = "ATTACH ? AS ? KEY ?"; - static constexpr char EXPORT_SQL[] = "SELECT export_database('backup')"; - static constexpr char DETACH_BACKUP_SQL[] = "detach backup"; - static constexpr char PRAGMA_JOUR_MODE_EXP[] = "PRAGMA journal_mode"; - static constexpr char PRAGMA_VERSION[] = "PRAGMA user_version"; - static constexpr char DEFAULT_JOURNAL_MODE[] = "WAL"; - static constexpr char DB_DEFAULT_JOURNAL_MODE[] = "DELETE"; - static constexpr char WAL_SYNC_MODE[] = "FULL"; - static constexpr char MEMORY_DB_PATH[] = ":memory:"; - static constexpr char ENCRYPT_ALGO[] = "sha256"; - static constexpr char CODEC_HMAC_ALGO[] = "PRAGMA codec_hmac_algo=sha256"; - static constexpr char CODEC_REKEY_HMAC_ALGO[] = "PRAGMA codec_rekey_hmac_algo=sha256"; - static constexpr char CIPHER_DEFAULT_ATTACH_HMAC_ALGO[] = "PRAGMA cipher_default_attach_hmac_algo=sha256"; -}; - -class SqliteGlobalConfig { -public: - SqliteGlobalConfig(); - ~SqliteGlobalConfig(); - static void InitSqliteGlobalConfig(); - static void SqliteLogCallback(const void *data, int err, const char *msg); - static int GetReadConnectionCount(); - static std::string GetMemoryDbPath(); - static int GetPageSize(); - static std::string GetWalSyncMode(); - static int GetJournalFileSize(); - static int GetWalAutoCheckpoint(); - static std::string GetDefaultJournalMode(); -}; - -} // namespace NativeRdb -} // namespace OHOS - -#endif diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h deleted file mode 100644 index 0b070fa43efc83e5838a807c57a0bb9d22ba0a86..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 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 NATIVE_RDB_SQLITE_SQL_BUILDER_H -#define NATIVE_RDB_SQLITE_SQL_BUILDER_H - -#include -#include -#include -#include - -#include "rdb_store.h" -namespace OHOS { -namespace NativeRdb { -class SqliteSqlBuilder { -public: - SqliteSqlBuilder(); - ~SqliteSqlBuilder(); - static std::string BuildDeleteString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); - static std::string BuildUpdateString(const ValuesBucket &values, const std::string &tableName, - const std::vector &whereArgs, const std::string &index, const std::string &whereClause, - const std::string &group, const std::string &order, int limit, int offset, std::vector &bindArgs, - ConflictResolution conflictResolution); - static int BuildQueryString(bool distinct, const std::string &table, const std::vector &columns, - const std::string &whereClause, const std::string &groupBy, const std::string &indexName, - const std::string &orderBy, const int &limit, const int &offset, std::string &outSql); - static std::string BuildCountString(const std::string &tableName, const std::string &index, - const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); - static std::string BuildSqlStringFromPredicates(const std::string &index, const std::string &whereClause, - const std::string &group, const std::string &order, int limit, int offset); - static std::string BuildSqlStringFromPredicatesNoWhere(const std::string &index, const std::string &whereClause, - const std::string &group, const std::string &order, int limit, int offset); - static std::string BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns); - static std::string BuildCountString(const AbsRdbPredicates &predicates); - static std::string BuildSqlStringFromPredicates(const AbsPredicates &predicates); - -private: - static void AppendClause(std::string &builder, const std::string &name, const std::string &clause); - static void AppendColumns(std::string &builder, const std::vector &columns); -}; -} // namespace NativeRdb -} // namespace OHOS -#endif diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_statement.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_statement.h deleted file mode 100644 index dcfa00135ab6633731f785b72c0b47635973f488..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_statement.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021 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 NATIVE_RDB_SQLITE_STATEMENT_H -#define NATIVE_RDB_SQLITE_STATEMENT_H - -#include - -#include "sqlite3sym.h" -#include "value_object.h" - -namespace OHOS { -namespace NativeRdb { -class SqliteStatement { -public: - SqliteStatement(); - ~SqliteStatement(); - int Prepare(sqlite3 *dbHandle, const std::string &sql); - int Finalize(); - int BindArguments(const std::vector &bindArgs) const; - int ResetStatementAndClearBindings() const; - int Step() const; - - int GetColumnCount(int &count) const; - int GetColumnName(int index, std::string &columnName) const; - int GetColumnType(int index, int &columnType) const; - int GetColumnBlob(int index, std::vector &value) const; - int GetColumnString(int index, std::string &value) const; - int GetColumnLong(int index, int64_t &value) const; - int GetColumnDouble(int index, double &value) const; - int GetSize(int index, size_t &size) const; - int GetColumn(int index, ValueObject &value) const; - bool IsReadOnly() const; - sqlite3_stmt *GetSql3Stmt() const - { - return stmtHandle; - } - -private: - using Asset = ValueObject::Asset; - using Assets = ValueObject::Assets; - - int InnerBindArguments(const std::vector &bindArgs) const; - int IsValid(int index) const; - std::string sql; - sqlite3_stmt *stmtHandle; - bool readOnly; - int columnCount; - int numParameters; -}; - -} // namespace NativeRdb -} // namespace OHOS -#endif \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_utils.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_utils.h deleted file mode 100644 index f5264d716eb64c34ced8fedef90cb90cffc4c738..0000000000000000000000000000000000000000 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_utils.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 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 NATIVE_RDB_SQLITE_UTILS_H -#define NATIVE_RDB_SQLITE_UTILS_H - -#include -#include - -namespace OHOS { -namespace NativeRdb { - -class SqliteUtils { -public: - static const int STATEMENT_SELECT; - static const int STATEMENT_UPDATE; - static const int STATEMENT_ATTACH; - static const int STATEMENT_DETACH; - static const int STATEMENT_BEGIN; - static const int STATEMENT_COMMIT; - static const int STATEMENT_ROLLBACK; - static const int STATEMENT_PRAGMA; - static const int STATEMENT_DDL; - static const int STATEMENT_OTHER; - static const int CONFLICT_CLAUSE_COUNT = 6; - - static int GetSqlStatementType(const std::string &sql); - static bool IsSqlReadOnly(int sqlType); - static bool IsSpecial(int sqlType); - static int GetConflictClause(int conflictResolution, std::string &conflictClause); - static std::string StrToUpper(std::string s); - static bool DeleteFile(const std::string path); - static int RenameFile(const std::string srcFile, const std::string destFile); - static std::string Anonymous(const std::string &srcFile); - static int GetFileSize(const std::string fileName); - -private: - static const std::map SQL_TYPE_MAP; - static const std::string ON_CONFLICT_CLAUSE[CONFLICT_CLAUSE_COUNT]; -}; - -} // namespace NativeRdb -} // namespace OHOS -#endif \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h index 35b72e84778551cfd99d78d0a6fb6e467b2d1513..8a7206b0d67f4be925087fa9ffa6e1f5b0e75e9b 100644 --- a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h @@ -76,7 +76,6 @@ private: static const int STEP_QUERY_RETRY_MAX_TIMES = 50; // Interval of retrying step query in millisecond static const int STEP_QUERY_RETRY_INTERVAL = 1000; - SqliteConnection *connection_; std::vector columnNames_; mutable std::shared_mutex mutex_; }; diff --git a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp index cf0a1e35617f8e84c1c07525c7154a49b1dafcba..1b757bcf4771d7468bf1d114990e6f5a12735b77 100644 --- a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp @@ -218,4 +218,37 @@ AbsRdbPredicates* AbsRdbPredicates::OrderByDesc(const std::string &field) predicates_.AddOperation(DistributedRdb::ORDER_BY, field, isAsc); return (AbsRdbPredicates *)AbsPredicates::OrderByDesc(field); } + +AbsPredicates *AbsRdbPredicates::BeginWrap() +{ + predicates_.AddOperation(DistributedRdb::BEGIN_GROUP, {}, ""); + return (AbsRdbPredicates *)AbsPredicates::BeginWrap(); +} + +AbsPredicates *AbsRdbPredicates::EndWrap() +{ + predicates_.AddOperation(DistributedRdb::END_GROUP, {}, ""); + return (AbsRdbPredicates *)AbsPredicates::EndWrap(); +} + +AbsPredicates *AbsRdbPredicates::In(const std::string &field, const std::vector &values) +{ + std::vector vals; + vals.reserve(values.size()); + for (const auto &value : values) { + auto val = std::get_if(&value.value); + if (val == nullptr) { + return (AbsRdbPredicates *)AbsPredicates::In(field, values); + } + vals.emplace_back(std::move(*val)); + } + predicates_.AddOperation(DistributedRdb::IN, field, vals); + return (AbsRdbPredicates *)AbsPredicates::In(field, values); +} + +AbsPredicates *AbsRdbPredicates::In(const std::string &field, const std::vector &values) +{ + predicates_.AddOperation(DistributedRdb::IN, field, values); + return (AbsRdbPredicates *)AbsPredicates::In(field, values); +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp index c559c541760fcd5b2e5f5e21d5c5633eac873e51..0f606d8ad024116397609a2efbf8f65392b62907 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp @@ -23,8 +23,10 @@ namespace OHOS::DistributedRdb { using namespace OHOS::Rdb; -RdbNotifierStub::RdbNotifierStub(const SyncCompleteHandler &completeNotifier, const DataChangeHandler &changeNotifier) - : IRemoteStub(), completeNotifier_(completeNotifier), changeNotifier_(changeNotifier) +RdbNotifierStub::RdbNotifierStub(const SyncCompleteHandler &completeNotifier, + const AutoSyncCompleteHandler &autoSyncCompleteHandler, const DataChangeHandler &changeNotifier) + : IRemoteStub(), completeNotifier_(completeNotifier), + autoSyncCompleteHandler_(autoSyncCompleteHandler), changeNotifier_(changeNotifier) { LOG_INFO("construct"); } @@ -79,6 +81,13 @@ int32_t RdbNotifierStub::OnComplete(uint32_t seqNum, Details &&result) return RDB_OK; } +int32_t RdbNotifierStub::OnComplete(const std::string &storeName, Details &&result) +{ + if (autoSyncCompleteHandler_) { + autoSyncCompleteHandler_(storeName, std::move(result)); + } + return RDB_OK; +} int32_t RdbNotifierStub::OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) { @@ -99,4 +108,15 @@ int32_t RdbNotifierStub::OnChangeInner(MessageParcel &data, MessageParcel &reply } return OnChange(origin, primaries, std::move(changeInfo)); } + +int32_t RdbNotifierStub::OnAutoSyncCompleteInner(MessageParcel &data, MessageParcel &reply) +{ + std::string storeName; + Details result; + if (!ITypesUtil::Unmarshal(data, storeName, result)) { + LOG_ERROR("read sync result failed"); + return RDB_ERROR; + } + return OnComplete(storeName, std::move(result)); +} } // namespace OHOS::DistributedRdb diff --git a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp index 6054d533e30ded85daaa945b836148b2bdfeee7c..4a701100736bd6a7b4590354a1d33cff89959650 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -55,36 +55,6 @@ RdbServiceProxy::RdbServiceProxy(const sptr &object) remote_ = Remote(); } -void RdbServiceProxy::OnSyncComplete(uint32_t seqNum, Details &&result) -{ - syncCallbacks_.ComputeIfPresent(seqNum, [&result] (const auto& key, const AsyncDetail & callback) { - auto finished = result.empty() || (result.begin()->second.progress == SYNC_FINISH); - LOG_DEBUG("Sync complete, seqNum%{public}d, result size:%{public}zu", key, result.size()); - if (callback!=nullptr) { - callback(std::move(result)); - } - return !finished; - }); -} - -void RdbServiceProxy::OnDataChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) -{ - LOG_DEBUG("store:%{public}s data change from :%{public}s, dataType:%{public}d, origin:%{public}d.", - SqliteUtils::Anonymous(origin.store).c_str(), - origin.id.empty() ? "empty" : SqliteUtils::Anonymous(*origin.id.begin()).c_str(), - origin.dataType, origin.origin); - auto name = RemoveSuffix(origin.store); - observers_.ComputeIfPresent(name, - [&origin, &primaries, info = std::move(changeInfo)](const auto &key, const std::list &value) - mutable { - auto size = value.size(); - for (const auto ¶ms : value) { - params.observer->OnChange(origin, primaries, --size > 0 ? ChangeInfo(info) : std::move(info)); - } - return !value.empty(); - }); -} - std::string RdbServiceProxy::ObtainDistributedTableName(const std::string &device, const std::string &table) { return ""; @@ -96,6 +66,9 @@ int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam ¶m) [this] (uint32_t seqNum, Details &&result) { OnSyncComplete(seqNum, std::move(result)); }, + [this] (std::string storeName, Details &&result) { + OnSyncComplete(storeName, std::move(result)); + }, [this](const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) { OnDataChange(origin, primaries, std::move(changeInfo)); }); @@ -189,18 +162,17 @@ int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const Option &opti if (callback != nullptr) { asyncOption.seqNum = GetSeqNum(); if (!syncCallbacks_.Insert(asyncOption.seqNum, callback)) { - LOG_INFO("insert callback failed"); + LOG_ERROR("bundleName:%{public}s, storeName:%{public}s, insert callback failed", param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); return RDB_ERROR; } } - LOG_INFO("num=%{public}u", asyncOption.seqNum); + LOG_INFO("bundleName:%{public}s, storeName:%{public}s, num=%{public}u, start DoAsync", param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str(), asyncOption.seqNum); if (DoAsync(param, asyncOption, predicates) != RDB_OK) { - LOG_ERROR("failed"); syncCallbacks_.Erase(asyncOption.seqNum); return RDB_ERROR; } - - LOG_INFO("success"); return RDB_OK; } @@ -253,7 +225,7 @@ int32_t RdbServiceProxy::Subscribe(const RdbSyncerParam ¶m, const SubscribeO observers_.Compute(name, [observer, ¶m, &option](const auto &key, std::list &value) { for (const auto &element : value) { if (element.observer == observer) { - LOG_ERROR("duplicate observer"); + LOG_ERROR("duplicate observer, storeName:%{public}s", SqliteUtils::Anonymous(key).c_str()); return true; } } @@ -369,4 +341,124 @@ int32_t RdbServiceProxy::Delete(const RdbSyncerParam ¶m) } return status; } + +int32_t RdbServiceProxy::RegisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) +{ + if (observer == nullptr || param.storeName_.empty()) { + LOG_ERROR("bundleName:%{public}s, storeName:%{public}s, syncObserver is nullptr", param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); + return RDB_ERROR; + } + int32_t status = RDB_OK; + auto name = RemoveSuffix(param.storeName_); + syncObservers_.Compute(name, [this, ¶m, &status, observer](const auto &store, auto &observers) { + for (const auto &element : observers) { + if (element.get() == observer.get()) { + LOG_ERROR("duplicate observer, storeName:%{public}s", SqliteUtils::Anonymous(store).c_str()); + return true; + } + } + status = DoRegister(param); + if (status == RDB_OK) { + observers.push_back(observer); + } + return !observers.empty(); + }); + return status; +} + +int32_t RdbServiceProxy::DoRegister(const RdbSyncerParam ¶m) +{ + MessageParcel reply; + int32_t status = IPC_SEND( + static_cast(RdbServiceCode::RDB_SERVICE_CMD_REGISTER_AUTOSYNC_PROGRESS_OBSERVER), reply, param); + if (status != RDB_OK) { + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); + } + return status; +} + +int32_t RdbServiceProxy::UnregisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) +{ + if (observer == nullptr || param.storeName_.empty()) { + LOG_ERROR("bundleName:%{public}s, storeName:%{public}s, syncObserver is nullptr", param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); + return RDB_ERROR; + } + int32_t status = RDB_OK; + auto name = RemoveSuffix(param.storeName_); + syncObservers_.ComputeIfPresent(name, [this, ¶m, &status, observer](const auto &storeName, auto &observers) { + for (auto it = observers.begin(); it != observers.end();) { + if (it->get() != observer.get()) { + ++it; + continue; + } + status = DoUnRegister(param); + if (status == RDB_OK) { + it = observers.erase(it); + } + } + return !observers.empty(); + }); + return status; +} + +int32_t RdbServiceProxy::DoUnRegister(const RdbSyncerParam ¶m) +{ + MessageParcel reply; + int32_t status = IPC_SEND( + static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNREGISTER_AUTOSYNC_PROGRESS_OBSERVER), reply, param); + if (status != RDB_OK) { + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); + } + return status; +} + +void RdbServiceProxy::OnDataChange( + const Origin &origin, const RdbServiceProxy::PrimaryFields &primaries, RdbServiceProxy::ChangeInfo &&changeInfo) +{ + LOG_DEBUG("store:%{public}s data change from :%{public}s, dataType:%{public}d, origin:%{public}d.", + SqliteUtils::Anonymous(origin.store).c_str(), + origin.id.empty() ? "empty" : SqliteUtils::Anonymous(*origin.id.begin()).c_str(), + origin.dataType, origin.origin); + auto name = RdbServiceProxy::RemoveSuffix(origin.store); + observers_.ComputeIfPresent(name, [&origin, &primaries, info = std::move(changeInfo)]( + const auto &key, const std::list &value) mutable { + auto size = value.size(); + for (const auto ¶ms : value) { + params.observer->OnChange(origin, primaries, --size > 0 ? ChangeInfo(info) : std::move(info)); + } + return !value.empty(); + }); +} + +void RdbServiceProxy::OnSyncComplete(uint32_t seqNum, Details &&result) +{ + syncCallbacks_.ComputeIfPresent(seqNum, [&result] (const auto& key, const AsyncDetail& callback) { + auto finished = result.empty() || (result.begin()->second.progress == SYNC_FINISH); + LOG_DEBUG("Sync complete, seqNum%{public}d, result size:%{public}zu", key, result.size()); + if (callback!=nullptr) { + callback(std::move(result)); + } + return !finished; + }); +} + +void RdbServiceProxy::OnSyncComplete(const std::string &storeName, Details &&result) +{ + syncObservers_.ComputeIfPresent(storeName, [&result](const auto &key, const auto &observers) { + LOG_DEBUG("Sync complete, storeName%{public}s, result size:%{public}zu", SqliteUtils::Anonymous(key).c_str(), + result.size()); + for (const auto &observer : observers) { + if (observer != nullptr) { + observer->ProgressNotification(result); + } + } + return true; + }); +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp index 6cc196363521561a4f2d6df9e177910c952dcd02..ecd001e497e5de987493000889b0f70cc63b19b1 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -34,20 +34,58 @@ namespace OHOS { namespace NativeRdb { +int RdbSqlUtils::CreateDirectory(const std::string &databaseDir) +{ + std::string tempDirectory = databaseDir; + std::vector directories; + + size_t pos = tempDirectory.find('/'); + while (pos != std::string::npos) { + std::string directory = tempDirectory.substr(0, pos); + directories.push_back(directory); + tempDirectory = tempDirectory.substr(pos + 1); + pos = tempDirectory.find('/'); + } + directories.push_back(tempDirectory); + + std::string databaseDirectory; + for (const std::string& directory : directories) { + databaseDirectory = databaseDirectory + "/" + directory; + if (access(databaseDirectory.c_str(), F_OK) != 0) { + if (MKDIR(databaseDirectory.c_str())) { + return E_CREATE_FOLDER_FAIL; + } + } + } + return E_OK; +} + +/** + * @brief get custom data base path. + */ +std::pair RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, + const std::string &customDir) +{ + int errorCode = E_OK; + if (customDir.empty()) { + return std::make_pair(GetDefaultDatabasePath(baseDir, name, errorCode), errorCode); + } + + std::string databaseDir; + databaseDir.append(baseDir).append("/rdb/").append(customDir); + + errorCode = CreateDirectory(databaseDir); + return std::make_pair(databaseDir.append("/").append(name), errorCode); +} /** * Get and Check default path. */ std::string RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, int &errorCode) { - errorCode = E_OK; - std::string databasePath = baseDir + "/rdb"; - if (access(databasePath.c_str(), F_OK) != 0) { - if (MKDIR(databasePath.c_str())) { - errorCode = E_CREATE_FOLDER_FAIL; - } - } - return databasePath.append("/").append(name); + std::string databaseDir = baseDir + "/rdb"; + errorCode = CreateDirectory(databaseDir); + return databaseDir.append("/").append(name); } std::string RdbSqlUtils::BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns) diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp index 4c04b9baab0f883aa78685ff273d77e8f6705f9a..ce58377c0cf0ddb006fa68613fd4bc0541fb6f2c 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp @@ -398,4 +398,14 @@ std::string RdbStoreConfig::GetDataGroupId() const { return dataGroupId_; } + +void RdbStoreConfig::SetCustomDir(const std::string &customDir) +{ + customDir_ = customDir; +} + +std::string RdbStoreConfig::GetCustomDir() const +{ + return customDir_; +} } // namespace OHOS::NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp index abb3212bf504a76de52e67c3f7ceb5713da7f008..edab08d06ddcca7b8534fce5188e80ded1812351 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -69,6 +69,7 @@ int RdbStoreImpl::InnerOpen() syncerParam_.bundleName_ = rdbStoreConfig.GetBundleName(); syncerParam_.hapName_ = rdbStoreConfig.GetModuleName(); syncerParam_.storeName_ = rdbStoreConfig.GetName(); + syncerParam_.customDir_ = rdbStoreConfig.GetCustomDir(); syncerParam_.area_ = rdbStoreConfig.GetArea(); syncerParam_.level_ = static_cast(rdbStoreConfig.GetSecurityLevel()); syncerParam_.type_ = rdbStoreConfig.GetDistributedType(); @@ -111,8 +112,55 @@ void RdbStoreImpl::GetSchema(const RdbStoreConfig &config) } } -std::map RdbStoreImpl::GetModifyTime( - const std::string &table, const std::string &columnName, std::vector &keys) +RdbStore::ModifyTime::ModifyTime(std::shared_ptr result, std::map, PRIKey> hashKeys, + bool isFromRowId) + : result_(std::move(result)), hash_(std::move(hashKeys)), isFromRowId_(isFromRowId) +{ +} + +RdbStore::ModifyTime::operator std::map() +{ + if (result_ == nullptr) { + return {}; + } + int count = 0; + if (result_->GetRowCount(count) != E_OK || count <= 0) { + LOG_ERROR("get resultSet err."); + return {}; + } + std::map result; + for (int i = 0; i < count; i++) { + result_->GoToRow(i); + int64_t timeStamp = 0; + result_->GetLong(1, timeStamp); + PRIKey index = 0; + if (isFromRowId_) { + int rowid = 0; + result_->GetInt(0, rowid); + index = rowid; + } else { + std::vector hashKey; + result_->GetBlob(0, hashKey); + index = hash_[hashKey]; + } + result[index] = Date(timeStamp); + } + return result; +} + +RdbStore::ModifyTime::operator std::shared_ptr() +{ + return result_; +} + +RdbStore::PRIKey RdbStore::ModifyTime::GetOriginKey(const std::vector &hash) +{ + auto it = hash_.find(hash); + return it != hash_.end() ? it->second : std::monostate(); +} + +RdbStore::ModifyTime RdbStoreImpl::GetModifyTime(const std::string &table, const std::string &columnName, + std::vector &keys) { if (table.empty() || columnName.empty() || keys.empty()) { LOG_ERROR("invalid para."); @@ -152,20 +200,10 @@ std::map RdbStoreImpl::GetModifyTime( LOG_ERROR("get resultSet err."); return {}; } - std::map result; - for (int i = 0; i < count; i++) { - resultSet->GoToRow(i); - std::vector hashKey; - int64_t timeStamp; - resultSet->GetBlob(0, hashKey); - resultSet->GetLong(1, timeStamp); - result[keyMap[hashKey]] = Date(timeStamp); - } - return result; + return { resultSet, keyMap, false }; } -std::map RdbStoreImpl::GetModifyTimeByRowId( - const std::string &logTable, std::vector &keys) +RdbStore::ModifyTime RdbStoreImpl::GetModifyTimeByRowId(const std::string &logTable, std::vector &keys) { std::string sql; sql.append("select data_key, timestamp/10000 from "); @@ -186,16 +224,7 @@ std::map RdbStoreImpl::GetModifyTimeByRowId( LOG_ERROR("get resultSet err."); return {}; } - std::map result; - for (int i = 0; i < count; i++) { - resultSet->GoToRow(i); - int rowId; - int64_t timeStamp; - resultSet->GetInt(0, rowId); - resultSet->GetLong(1, timeStamp); - result[rowId] = Date(timeStamp); - } - return result; + return { resultSet, {}, true }; } #endif @@ -962,7 +991,8 @@ int RdbStoreImpl::SetVersion(int version) int RdbStoreImpl::BeginTransaction() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - BaseTransaction transaction(connectionPool->getTransactionStack().size()); + std::lock_guard lockGuard(connectionPool->GetTransactionStackMutex()); + BaseTransaction transaction(connectionPool->GetTransactionStack().size()); SqliteConnection *connection = connectionPool->AcquireConnection(false); if (connection == nullptr) { return E_CON_OVER_LIMIT; @@ -976,7 +1006,7 @@ int RdbStoreImpl::BeginTransaction() } connection->SetInTransaction(true); - connectionPool->getTransactionStack().push(transaction); + connectionPool->GetTransactionStack().push(transaction); return E_OK; } @@ -986,13 +1016,14 @@ int RdbStoreImpl::BeginTransaction() int RdbStoreImpl::RollBack() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - if (connectionPool->getTransactionStack().empty()) { + std::lock_guard lockGuard(connectionPool->GetTransactionStackMutex()); + if (connectionPool->GetTransactionStack().empty()) { return E_NO_TRANSACTION_IN_SESSION; } - BaseTransaction transaction = connectionPool->getTransactionStack().top(); - connectionPool->getTransactionStack().pop(); - if (transaction.GetType() != TransType::ROLLBACK_SELF && !connectionPool->getTransactionStack().empty()) { - connectionPool->getTransactionStack().top().SetChildFailure(true); + BaseTransaction transaction = connectionPool->GetTransactionStack().top(); + connectionPool->GetTransactionStack().pop(); + if (transaction.GetType() != TransType::ROLLBACK_SELF && !connectionPool->GetTransactionStack().empty()) { + connectionPool->GetTransactionStack().top().SetChildFailure(true); } SqliteConnection *connection = connectionPool->AcquireConnection(false); if (connection == nullptr) { @@ -1001,7 +1032,7 @@ int RdbStoreImpl::RollBack() int errCode = connection->ExecuteSql(transaction.GetRollbackStr()); connectionPool->ReleaseConnection(connection); - if (connectionPool->getTransactionStack().empty()) { + if (connectionPool->GetTransactionStack().empty()) { connection->SetInTransaction(false); } if (errCode != E_OK) { @@ -1018,13 +1049,14 @@ int RdbStoreImpl::Commit() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); LOG_DEBUG("Enter Commit."); - if (connectionPool->getTransactionStack().empty()) { + std::lock_guard lockGuard(connectionPool->GetTransactionStackMutex()); + if (connectionPool->GetTransactionStack().empty()) { return E_OK; } - BaseTransaction transaction = connectionPool->getTransactionStack().top(); + BaseTransaction transaction = connectionPool->GetTransactionStack().top(); std::string sqlStr = transaction.GetCommitStr(); if (sqlStr.size() <= 1) { - connectionPool->getTransactionStack().pop(); + connectionPool->GetTransactionStack().pop(); return E_OK; } @@ -1036,7 +1068,7 @@ int RdbStoreImpl::Commit() int errCode = connection->ExecuteSql(sqlStr); connectionPool->ReleaseConnection(connection); connection->SetInTransaction(false); - connectionPool->getTransactionStack().pop(); + connectionPool->GetTransactionStack().pop(); if (errCode != E_OK) { LOG_ERROR("Commit Failed."); } @@ -1217,8 +1249,9 @@ void RdbStoreImpl::DoCloudSync(const std::string &table) if (ptr == nullptr) { return; } - SyncOption syncOption = { DistributedRdb::TIME_FIRST, false }; - Sync(syncOption, { ptr->begin(), ptr->end() }, nullptr); + DistributedRdb::RdbService::Option option = { DistributedRdb::TIME_FIRST, 0, true, true }; + InnerSync(option, + AbsRdbPredicates(std::vector(ptr->begin(), ptr->end())).GetDistributedPredicates(), nullptr); }); #endif } @@ -1341,46 +1374,41 @@ std::string RdbStoreImpl::ObtainDistributedTableName(const std::string &device, } int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncBrief &callback) +{ + return Sync(option, predicate, [callback](Details &&details) { + Briefs briefs; + for (auto &[key, value] : details) { + briefs.insert_or_assign(key, value.code); + } + if (callback != nullptr) { + callback(briefs); + } + }); +} + +int RdbStoreImpl::Sync(const SyncOption &option, const std::vector &tables, const AsyncDetail &async) +{ + return Sync(option, AbsRdbPredicates(tables), async); +} + +int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); - if (errCode != E_OK) { - LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); - return errCode; - } DistributedRdb::RdbService::Option rdbOption; rdbOption.mode = option.mode; rdbOption.isAsync = !option.isBlock; - errCode = - service->Sync(syncerParam_, rdbOption, predicate.GetDistributedPredicates(), [callback](Details &&details) { - Briefs briefs; - for (auto &[key, value] : details) { - briefs.insert_or_assign(key, value.code); - } - if (callback != nullptr) { - callback(briefs); - } - }); - if (errCode != E_OK) { - LOG_ERROR("Sync is failed, err is %{public}d.", errCode); - return errCode; - } - return E_OK; + return InnerSync(rdbOption, predicate.GetDistributedPredicates(), async); } -int RdbStoreImpl::Sync(const SyncOption &option, const std::vector &tables, - const AsyncDetail &async) +int RdbStoreImpl::InnerSync(const DistributedRdb::RdbService::Option &option, + const DistributedRdb::PredicatesMemo &predicates, const RdbStore::AsyncDetail &async) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); return errCode; } - DistributedRdb::RdbService::Option rdbOption; - rdbOption.mode = option.mode; - rdbOption.isAsync = !option.isBlock; - errCode = service->Sync(syncerParam_, rdbOption, AbsRdbPredicates(tables).GetDistributedPredicates(), async); + errCode = service->Sync(syncerParam_, option, predicates, async); if (errCode != E_OK) { LOG_ERROR("Sync is failed, err is %{public}d.", errCode); return errCode; @@ -1602,5 +1630,23 @@ int RdbStoreImpl::Notify(const std::string &event) } return E_OK; } + +int RdbStoreImpl::RegisterAutoSyncCallback(std::shared_ptr observer) +{ + auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + if (errCode != E_OK) { + return errCode; + } + return service->RegisterAutoSyncCallback(syncerParam_, observer); +} + +int RdbStoreImpl::UnregisterAutoSyncCallback(std::shared_ptr observer) +{ + auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + if (errCode != E_OK) { + return errCode; + } + return service->UnregisterAutoSyncCallback(syncerParam_, observer); +} #endif } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index 1cf2d6b135683099f60969e849f22fcac13f964e..4afd9f3d804849175f4553abe637115d59791c88 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -45,7 +45,7 @@ RdbStoreManager &RdbStoreManager::GetInstance() RdbStoreManager::~RdbStoreManager() { - LOG_ERROR("Start"); + LOG_INFO("Start"); Clear(); } @@ -58,6 +58,7 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con { std::string path = config.GetPath(); std::lock_guard lock(mutex_); // TOD this lock should only work on storeCache_, add one more lock for connectionpool + bundleName_ = config.GetBundleName(); if (storeCache_.find(path) != storeCache_.end()) { std::shared_ptr rdbStore = storeCache_[path].lock(); if (rdbStore != nullptr && rdbStore->GetConfig() == config) { @@ -166,6 +167,8 @@ bool RdbStoreManager::Delete(const std::string &path) if (!tokens.empty()) { DistributedRdb::RdbSyncerParam param; param.storeName_ = *tokens.rbegin(); + std::lock_guard lock(mutex_); + param.bundleName_ = bundleName_; auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); if (err == E_OK && service != nullptr) { err = service->Delete(param); diff --git a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp index 88ebca6aa527560af13f339c423e9f77596abe4e..eb9640738f13289c56ad56e3a5b3fa16116bae82 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp @@ -19,25 +19,25 @@ template<> bool Marshalling(const SyncerParam &input, MessageParcel &data) { return ITypesUtil::Marshal(data, input.bundleName_, input.hapName_, input.storeName_, input.area_, - input.level_, input.type_, input.isAutoSync_, input.isEncrypt_, input.password_); + input.level_, input.type_, input.isEncrypt_, input.password_, input.customDir_); } template<> bool Unmarshalling(SyncerParam &output, MessageParcel &data) { return ITypesUtil::Unmarshal(data, output.bundleName_, output.hapName_, output.storeName_, output.area_, - output.level_, output.type_, output.isAutoSync_, output.isEncrypt_, output.password_); + output.level_, output.type_, output.isEncrypt_, output.password_, output.customDir_); } template<> bool Marshalling(const Option &input, MessageParcel &data) { - return ITypesUtil::Marshal(data, input.mode, input.seqNum, input.isAsync); + return ITypesUtil::Marshal(data, input.mode, input.seqNum, input.isAsync, input.isAutoSync); } template<> bool Unmarshalling(Option &output, MessageParcel &data) { - return ITypesUtil::Unmarshal(data, output.mode, output.seqNum, output.isAsync); + return ITypesUtil::Unmarshal(data, output.mode, output.seqNum, output.isAsync, output.isAutoSync); } template<> diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index b5344be8fd25ccf1c48357e9d9ed1766941b0b7b..726cc37dc05f2064911d8854bfa921b3e0b33d90 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -114,7 +114,7 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) #endif isReadOnly = !isWriteConnection || config.IsReadOnly(); int openFileFlags = config.IsReadOnly() ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); - int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle, openFileFlags, nullptr); + int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle, openFileFlags | SQLITE_OPEN_FULLMUTEX, nullptr); if (errCode != SQLITE_OK) { LOG_ERROR("SqliteConnection InnerOpen fail to open database err = %{public}d", errCode); #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp index 1ede34955adae91d2a27529a4599f5f1206eb9bf..cfb2d171bd2d5ee453689fca2d3827dbaafc0239 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp @@ -33,7 +33,7 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -constexpr std::chrono::seconds WAIT_CONNECT_TIMEOUT(2); +constexpr std::chrono::seconds WAIT_CONNECT_TIMEOUT(1); SqliteConnectionPool *SqliteConnectionPool::Create(const RdbStoreConfig &storeConfig, int &errCode) { @@ -311,9 +311,14 @@ int SqliteConnectionPool::ChangeDbFileForRestore(const std::string newPath, cons return Init(); } -std::stack &SqliteConnectionPool::getTransactionStack() +std::stack &SqliteConnectionPool::GetTransactionStack() { return transactionStack; } + +std::mutex &SqliteConnectionPool::GetTransactionStackMutex() +{ + return transactionStackMutex; +} } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp index 67aede4eb2746732e37b089c637e7a8c24e318c6..3ef44eb08f5ad906e83299399103d9e3f292f9d4 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp @@ -23,6 +23,7 @@ #include "rdb_errno.h" #include "sqlite_errno.h" #include "sqlite_utils.h" +#include "sqlite_connection.h" namespace OHOS { namespace NativeRdb { @@ -33,11 +34,32 @@ const int SET_DATA_PRECISION = 15; SqliteStatement::SqliteStatement() : sql(""), stmtHandle(nullptr), readOnly(false), columnCount(0), numParameters(0) { } + SqliteStatement::~SqliteStatement() { Finalize(); } +std::shared_ptr SqliteStatement::CreateStatement( + SqliteConnection *connection, const std::string &sql) +{ + sqlite3_stmt *stmt = nullptr; + int errCode = sqlite3_prepare_v2(connection->dbHandle, sql.c_str(), sql.length(), &stmt, nullptr); + if (errCode != SQLITE_OK) { + LOG_ERROR("prepare_v2 ret is %{public}d", errCode); + if (stmt != nullptr) { + sqlite3_finalize(stmt); + } + return nullptr; + } + std::shared_ptr sqliteStatement = std::make_shared(); + sqliteStatement->stmtHandle = stmt; + sqliteStatement->readOnly = (sqlite3_stmt_readonly(stmt) != 0) ? true : false; + sqliteStatement->columnCount = sqlite3_column_count(stmt); + sqliteStatement->numParameters = sqlite3_bind_parameter_count(stmt); + return sqliteStatement; +} + int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) { if (sql.compare(newSql) == 0) { @@ -240,14 +262,25 @@ int SqliteStatement::GetColumnType(int index, int &columnType) const } int type = sqlite3_column_type(stmtHandle, index); + auto declType = SqliteUtils::StrToUpper(std::string(sqlite3_column_decltype(stmtHandle, index))); switch (type) { case SQLITE_INTEGER: case SQLITE_FLOAT: - case SQLITE_BLOB: case SQLITE_NULL: case SQLITE_TEXT: columnType = type; return E_OK; + case SQLITE_BLOB: + if (declType == ValueObject::DeclType()) { + columnType = COLUMN_TYPE_ASSET; + return E_OK; + } + if (declType == ValueObject::DeclType()) { + columnType = COLUMN_TYPE_ASSETS; + return E_OK; + } + columnType = type; + return E_OK; default: LOG_ERROR("invalid type %{public}d.", type); return E_ERROR; diff --git a/relational_store/frameworks/native/rdb/src/step_result_set.cpp b/relational_store/frameworks/native/rdb/src/step_result_set.cpp index b6400bf45fd0a546671f846e1cf9537ee56ee69a..58acc0eac8498060b906a0215484d482b2a5ad7e 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -32,8 +32,9 @@ using namespace OHOS::Rdb; StepResultSet::StepResultSet(std::shared_ptr rdb, SqliteConnectionPool *connectionPool, const std::string &sql, const std::vector &selectionArgs) : rdb(rdb), connectionPool_(connectionPool), sql(sql), args_(std::move(selectionArgs)), isAfterLast(false), - rowCount(INIT_POS), sqliteStatement(nullptr), connection_(connectionPool_->AcquireConnection(true)) + rowCount(INIT_POS), sqliteStatement(nullptr) { + PrepareStep(); } StepResultSet::~StepResultSet() @@ -93,6 +94,10 @@ int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) LOG_ERROR("query not executed."); return E_STEP_RESULT_QUERY_NOT_EXECUTED; } + if (sqliteStatement == nullptr) { + LOG_ERROR("sqliteStatement init failed!"); + return E_CON_OVER_LIMIT; + } int sqliteType; int errCode = sqliteStatement->GetColumnType(columnIndex, sqliteType); if (errCode) { @@ -110,6 +115,12 @@ int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) case SQLITE_BLOB: columnType = ColumnType::TYPE_BLOB; break; + case SqliteStatement::COLUMN_TYPE_ASSET: + columnType = ColumnType::TYPE_ASSET; + break; + case SqliteStatement::COLUMN_TYPE_ASSETS: + columnType = ColumnType::TYPE_ASSETS; + break; case SQLITE_NULL: columnType = ColumnType::TYPE_NULL; break; @@ -144,10 +155,6 @@ int StepResultSet::GetRowCount(int &count) */ int StepResultSet::GoToRow(int position) { - if (connection_ == nullptr) { - LOG_ERROR("Failed as too many connections"); - return E_CON_OVER_LIMIT; - } // If the moved position is less than zero, reset the result and return an error if (position < 0) { LOG_DEBUG("position %{public}d.", position); @@ -227,11 +234,7 @@ int StepResultSet::Close() return E_OK; } isClosed = true; - int errCode = FinishStep(); - - connectionPool_->ReleaseConnection(connection_); - connection_ = nullptr; - return errCode; + return FinishStep(); } /** @@ -243,24 +246,30 @@ int StepResultSet::PrepareStep() return E_OK; } - if (connection_ == nullptr) { - LOG_ERROR("too many connections"); - return E_CON_OVER_LIMIT; - } - if (SqliteUtils::GetSqlStatementType(sql) != SqliteUtils::STATEMENT_SELECT) { LOG_ERROR("not a select sql!"); return E_EXECUTE_IN_STEP_QUERY; } - int errCode; - sqliteStatement = connection_->BeginStepQuery(errCode, sql, args_); + SqliteConnection *connection = connectionPool_->AcquireConnection(true); + if (connection == nullptr) { + LOG_ERROR("connectionPool_ AcquireConnection failed!"); + return E_CON_OVER_LIMIT; + } + sqliteStatement = SqliteStatement::CreateStatement(connection, sql); + connectionPool_->ReleaseConnection(connection); if (sqliteStatement == nullptr) { - connection_->EndStepQuery(); - LOG_ERROR("BeginStepQuery ret is %{public}d", errCode); - return errCode; + LOG_ERROR("Connection create statement failed!"); + return E_STATEMENT_NOT_PREPARED; } + int errCode = sqliteStatement->BindArguments(args_); + if (errCode != E_OK) { + LOG_ERROR("Bind arg faild! Ret is %{public}d", errCode); + sqliteStatement->ResetStatementAndClearBindings(); + sqliteStatement = nullptr; + return errCode; + } return E_OK; } @@ -269,21 +278,12 @@ int StepResultSet::PrepareStep() */ int StepResultSet::FinishStep() { - if (sqliteStatement == nullptr) { - return E_OK; + if (sqliteStatement != nullptr) { + sqliteStatement->ResetStatementAndClearBindings(); + sqliteStatement = nullptr; } - - sqliteStatement = nullptr; rowPos_ = INIT_POS; - if (connection_ == nullptr) { - return E_OK; - } - - int errCode = connection_->EndStepQuery(); - if (errCode != E_OK) { - LOG_ERROR("ret is %d", errCode); - } - return errCode; + return E_OK; } /** @@ -291,10 +291,7 @@ int StepResultSet::FinishStep() */ void StepResultSet::Reset() { - if (sqliteStatement != nullptr) { - sqlite3_reset(sqliteStatement->GetSql3Stmt()); - } - rowPos_ = INIT_POS; + FinishStep(); isAfterLast = false; } diff --git a/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp b/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp index 8243941390a84e39e50a006bab15d47737b8e932..31eaa6a8ee08b9fdca61fb739cf55f97e2cb7450 100644 --- a/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp +++ b/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp @@ -125,8 +125,7 @@ std::vector DataShareProfileInfo::GetResProfileByMetadata( std::shared_ptr DataShareProfileInfo::InitResMgr(const std::string &resourcePath) { - std::lock_guard lock(infosMutex_); - static std::shared_ptr resMgr(CreateResourceManager()); + std::shared_ptr resMgr(CreateResourceManager()); if (resMgr == nullptr) { return nullptr; } diff --git a/relational_store/interfaces/inner_api/rdb/BUILD.gn b/relational_store/interfaces/inner_api/rdb/BUILD.gn index 9dd419b1438c02feeba3eaa871f88a6fd41b2936..33674a1d2f19abbd671fc3fefc9b0e6ea3013013 100644 --- a/relational_store/interfaces/inner_api/rdb/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb/BUILD.gn @@ -66,6 +66,7 @@ if (is_ohos && !build_ohos_sdk) { defines += [ "SQLITE_DISTRIBUTE_RELATIONAL" ] include_dirs += [ "${kvstore_path}/common", + "${kvstore_interface_path}", "${distributedfile_path}/mod_securitylabel", ] } diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h index d709938e136c747d07104b415e0d1520fc1afed6..f3820e1242e07712e97ef5134765c786718f7e12 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h @@ -123,6 +123,34 @@ public: */ API_EXPORT AbsRdbPredicates* Or() override; + /** + * @brief Adds an left bracket condition to the remote AbsRdbPredicates. + * + * This method is similar to left bracket of the SQL statement. + */ + API_EXPORT AbsPredicates *BeginWrap() override; + + /** + * @brief Adds an right bracket condition to the remote AbsRdbPredicates. + * + * This method is similar to right bracket of the SQL statement. + */ + API_EXPORT virtual AbsPredicates *EndWrap() override; + + /** + * @brief Adds an In condition to the remote AbsRdbPredicates. + * + * This method is similar to In of the SQL statement. + */ + API_EXPORT virtual AbsPredicates *In(const std::string &field, const std::vector &values) override; + + /** + * @brief Adds an In condition to the remote AbsRdbPredicates. + * + * This method is similar to In of the SQL statement. + */ + API_EXPORT virtual AbsPredicates *In(const std::string &field, const std::vector &values) override; + /** * @brief Restricts the ascending order of the return list. When there are several orders, * the one close to the head has the highest priority. diff --git a/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h b/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h index 491bcd20f4ad1309d4fa08e4882ecde337ebcc65..784458a1bc169d4b2d0c9235b1b07bfd9603e130 100644 --- a/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h +++ b/relational_store/interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h @@ -22,6 +22,7 @@ namespace OHOS::DistributedRdb { namespace RelationalStore { enum class IRdbNotifierInterfaceCode { RDB_NOTIFIER_CMD_SYNC_COMPLETE = 0, + RDB_NOTIFIER_CMD_AUTO_SYNC_COMPLETE, RDB_NOTIFIER_CMD_DATA_CHANGE, RDB_NOTIFIER_CMD_MAX }; @@ -76,6 +77,8 @@ enum class RdbServiceInterfaceCode { RDB_SERVICE_CMD_REMOTE_QUERY, RDB_SERVICE_CMD_GET_SCHEMA, RDB_SERVICE_CMD_DELETE, + RDB_SERVICE_CMD_REGISTER_AUTOSYNC_PROGRESS_OBSERVER, + RDB_SERVICE_CMD_UNREGISTER_AUTOSYNC_PROGRESS_OBSERVER, RDB_SERVICE_CMD_MAX }; } // namespace RelationalStore diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_notifier.h b/relational_store/interfaces/inner_api/rdb/include/rdb_notifier.h index 11d5e0b925e6e678b0bed8d38ec90689b3238980..d31080f0e459babcc6298d49a5ddc3bb25158d12 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_notifier.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_notifier.h @@ -23,6 +23,7 @@ public: using ChangeInfo = RdbStoreObserver::ChangeInfo; using PrimaryFields = std::map; virtual int32_t OnComplete(uint32_t seqNum, Details &&result) = 0; + virtual int32_t OnComplete(const std::string& storeName, Details &&result) = 0; virtual int32_t OnChange(const Origin &origin, const PrimaryFields &primaries, ChangeInfo &&changeInfo) = 0; }; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h index 4d3dbc49a15bf4dfc1bdeeffc4dd1f9ba1a066f5..92fe6ea8c7028faac19f9eeb44cc55d3c2f2995d 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h @@ -34,6 +34,7 @@ public: int32_t mode; uint32_t seqNum = 0; bool isAsync = false; + bool isAutoSync = false; }; virtual std::string ObtainDistributedTableName(const std::string &device, const std::string &table) = 0; @@ -50,6 +51,12 @@ public: virtual int32_t UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) = 0; + virtual int32_t RegisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) = 0; + + virtual int32_t UnregisterAutoSyncCallback( + const RdbSyncerParam ¶m, std::shared_ptr observer) = 0; + virtual int32_t RemoteQuery(const RdbSyncerParam ¶m, const std::string &device, const std::string &sql, const std::vector &selectionArgs, sptr &resultSet) = 0; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h b/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h index c8d05716296ef64305f24a432b0fa3b03181bb1d..7bb74cffc9e9fe76f6b060cb9aec182a537006aa 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h @@ -21,10 +21,22 @@ namespace OHOS { namespace NativeRdb { class API_EXPORT RdbSqlUtils { public: + /** + * @brief create data base directory. + */ + static int CreateDirectory(const std::string &databaseDir); + + /** + * @brief get custom data base path. + */ + static std::pair GetDefaultDatabasePath(const std::string &baseDir, + const std::string &name, const std::string &customDir = ""); + /** * @brief get default data base path. */ static std::string GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, int &errorCode); + /** * @brief build query sql string. */ diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h index 847ce7f193a6dfc308959ebe739dcb03326d6271..aef5e799daad0758312ed1fcb2cb939181ad6692 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h @@ -70,6 +70,11 @@ public: using RdbStoreObserver = DistributedRdb::RdbStoreObserver; using PRIKey = RdbStoreObserver::PrimaryKey; + /** + * @brief Use RdbSyncObserver replace DistributedRdb::RdbSyncObserver namespace. + */ + using DetailProgressObserver = DistributedRdb::DetailProgressObserver; + /** * @brief Use Date replace DistributedRdb::Date namespace. */ @@ -464,6 +469,14 @@ public: virtual int Sync( const SyncOption &option, const std::vector &tables, const AsyncDetail &async) = 0; + /** + * @brief Sync data between devices or cloud. + * + * @param device Indicates the remote device. + * @param predicate Indicates the AbsRdbPredicates {@link AbsRdbPredicates} object. + */ + virtual int Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async) = 0; + /** * @brief Subscribe to event changes. */ @@ -474,11 +487,35 @@ public: */ virtual int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; + /** + * @brief Register message for auto sync operation. + */ + virtual int RegisterAutoSyncCallback(std::shared_ptr observer) = 0; + + /** + * @brief UnRegister message for auto sync operation. + */ + virtual int UnregisterAutoSyncCallback(std::shared_ptr observer) = 0; + /** * @brief When SubscribeMode is LOCAL or LOCALSHARED, this function needs to be called to trigger callback. */ virtual int Notify(const std::string &event) = 0; + class ModifyTime { + public: + ModifyTime() = default; + ModifyTime(std::shared_ptr result, std::map, PRIKey> hashKeys, + bool isFromRowId); + operator std::map(); + operator std::shared_ptr(); + PRIKey GetOriginKey(const std::vector& hash); + + private: + std::shared_ptr result_; + std::map, PRIKey> hash_; + bool isFromRowId_{ false }; + }; /** * @brief Get the the specified column modify time. * @@ -488,8 +525,8 @@ public: * * @return Returns the specified column modify time. */ - virtual std::map GetModifyTime( - const std::string &table, const std::string &columnName, std::vector &keys) = 0; + virtual ModifyTime GetModifyTime(const std::string& table, const std::string& columnName, + std::vector& keys) = 0; }; } // namespace OHOS::NativeRdb #endif diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h index a564f285e159a098da2d42bc83487f24fad71efa..c4a478531d519cf6d62cb02841a93616446dbcd5 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h @@ -452,6 +452,16 @@ public: */ std::string GetDataGroupId() const; + /** + * @brief Sets the customDir directory for the object. + */ + void SetCustomDir(const std::string &customDir); + + /** + * @brief Obtains the customDir directory in this {@code StoreConfig} object. + */ + std::string GetCustomDir() const; + /** * @brief Overload the line number operator. */ @@ -484,7 +494,7 @@ public: && this->syncMode == config.syncMode && this->databaseFileType == config.databaseFileType && this->isEncrypt_ == config.isEncrypt_ && this->securityLevel == config.securityLevel && this->journalSize == config.journalSize && this->pageSize == config.pageSize - && this->readConSize_ == config.readConSize_; + && this->readConSize_ == config.readConSize_ && this->customDir_ == config.customDir_; } private: @@ -519,6 +529,7 @@ private: int readConSize_ = 4; std::string encryptAlgo; std::string dataGroupId_; + std::string customDir_; std::map customScalarFunctions; }; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h index 2771aab769ff75b10b4701e7eb073c486d89b5c3..c035b409ce3a2bab9a619c04aa8546f0c93f5eec 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h @@ -40,10 +40,10 @@ struct RdbSyncerParam { std::string bundleName_; std::string hapName_; std::string storeName_; + std::string customDir_; int32_t area_ = 0; int32_t level_ = 0; int32_t type_ = RDB_DEVICE_COLLABORATION; - bool isAutoSync_ = false; bool isEncrypt_ = false; std::vector password_; ~RdbSyncerParam() @@ -126,6 +126,9 @@ enum RdbPredicateOperator { OR, ORDER_BY, LIMIT, + BEGIN_GROUP, + END_GROUP, + IN, OPERATOR_MAX }; @@ -162,6 +165,13 @@ struct Date { int64_t date; }; +class DetailProgressObserver { +public: + virtual ~DetailProgressObserver() {}; + + virtual void ProgressNotification(const Details& details) = 0; +}; + enum SubscribeMode { REMOTE, CLOUD, diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h index dfa86e7c639700004d5fad4fd7c24d9a6d90241e..ec392e9b500d5fd8ef25d0463a1d49af13e492a3 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h @@ -138,6 +138,8 @@ public: void SetScalarFunction(const std::string &functionName, int argc, ScalarFunction function); void SetDataGroupId(const std::string &dataGroupId); std::string GetDataGroupId() const; + void SetCustomDir(const std::string &customDir); + std::string GetCustomDir() const; std::map GetScalarFunctions() const; bool operator==(const RdbStoreConfig &config) const @@ -169,7 +171,7 @@ public: && this->syncMode == config.syncMode && this->databaseFileType == config.databaseFileType && this->isEncrypt_ == config.isEncrypt_ && this->securityLevel == config.securityLevel && this->journalSize == config.journalSize && this->pageSize == config.pageSize - && this->readConSize_ == config.readConSize_; + && this->readConSize_ == config.readConSize_ && this->customDir_ == config.customDir_; } private: @@ -199,6 +201,7 @@ private: int readConSize_ = 4; std::string encryptAlgo; std::string dataGroupId_; + std::string customDir_; std::map customScalarFunctions; }; diff --git a/relational_store/interfaces/ndk/BUILD.gn b/relational_store/interfaces/ndk/BUILD.gn index 51d6323e4bc53021e4ba858de9d0c67bda776ea3..a720869f7ad9535b58e3c9104cfef3166c6d54e1 100644 --- a/relational_store/interfaces/ndk/BUILD.gn +++ b/relational_store/interfaces/ndk/BUILD.gn @@ -27,13 +27,19 @@ ohos_ndk_headers("native_rdb_ndk_header") { ] } +ohos_ndk_headers("data_ndk_header") { + dest_dir = "$ndk_headers_out_dir/database/data/" + sources = [ "./include/data_asset.h" ] +} + ohos_ndk_library("libnative_rdb_ndk") { output_name = "native_rdb_ndk" system_capability = "SystemCapability.DistributedDataManager.RelationalStore.Core" ndk_description_file = "./libnative_rdb.ndk.json" - min_compact_version = "10" + min_compact_version = "11" system_capability_headers = [ + "$ndk_headers_out_dir/database/data/data_asset.h", "$ndk_headers_out_dir/database/rdb/oh_cursor.h", "$ndk_headers_out_dir/database/rdb/oh_predicates.h", "$ndk_headers_out_dir/database/rdb/oh_value_object.h", diff --git a/relational_store/interfaces/ndk/include/data_asset.h b/relational_store/interfaces/ndk/include/data_asset.h new file mode 100644 index 0000000000000000000000000000000000000000..ede58debc288edabedcfd409172dbeac6cd41a37 --- /dev/null +++ b/relational_store/interfaces/ndk/include/data_asset.h @@ -0,0 +1,316 @@ +/* + * 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 DATA_ASSET_H +#define DATA_ASSET_H +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @since 11 + */ + +/** + * @file data_asset.h + * + * @brief Provides the data type of asset. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 11 + */ +#include +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief Describes the status of asset. + * + * @since 11 + */ +typedef enum Data_AssetStatus { + /** + * @brief Means the status of asset is null. + */ + ASSET_NULL = 0, + + /** + * @brief Means the status of asset is normal. + */ + ASSET_NORMAL, + + /** + * @brief Means the asset needs to be inserted. + */ + ASSET_INSERT, + + /** + * @brief Means the asset needs to be updated. + */ + ASSET_UPDATE, + + /** + * @brief Means the asset needs to be deleted. + */ + ASSET_DELETE, + + /** + * @brief Means the status of asset is abnormal. + */ + ASSET_ABNORMAL, + + /** + * @brief Means the status of asset is downloading. + */ + ASSET_DOWNLOADING +} Data_AssetStatus; + +/** + * @brief Define the Data_Asset structure type. + * + * Provides information of an asset. + * + * @since 11 + */ +typedef struct Data_Asset Data_Asset; + +/** + * @brief Set the name of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param name Indicates the name to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetName(Data_Asset *asset, const char *name); + +/** + * @brief Set the uri of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param uri Indicates the uri to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetUri(Data_Asset *asset, const char *uri); + +/** + * @brief Set the path of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param path Indicates the path to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetPath(Data_Asset *asset, const char *path); + +/** + * @brief Set the create time of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param createTime Indicates the create time to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetCreateTime(Data_Asset *asset, int64_t createTime); + +/** + * @brief Set the modify time of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param modifyTime Indicates the create time to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetModifyTime(Data_Asset *asset, int64_t modifyTime); + +/** + * @brief Set the size of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param size Indicates the size to set. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_SetSize(Data_Asset *asset, size_t size); + +/** + * @brief Set the status of the Data_Asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param status Indicates the status to set. Specific status can be referenced {@link Data_AssetStatus}. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset, Data_AssetStatus + * @since 11 + */ +int OH_Data_Asset_SetStatus(Data_Asset *asset, Data_AssetStatus status); + +/** + * @brief Obtains the name of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param name This parameter is the output parameter, + * and the name of the asset as a char * is written to this variable. + * @param length Indicates the length of the name. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetName(Data_Asset *asset, char *name, size_t *length); + +/** + * @brief Obtains the uri of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param uri This parameter is the output parameter, + * and the uri of the asset as a char * is written to this variable. + * @param length Indicates the length of the uri. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetUri(Data_Asset *asset, char *uri, size_t *length); + +/** + * @brief Obtains the path of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param path This parameter is the output parameter, + * and the path of the asset as a char * is written to this variable. + * @param length Indicates the length of the path. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetPath(Data_Asset *asset, char *path, size_t *length); + +/** + * @brief Obtains the create time of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param createTime This parameter is the output parameter, + * and the create time of the asset as a int64_t is written to this variable. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetCreateTime(Data_Asset *asset, int64_t *createTime); + +/** + * @brief Obtains the modify time of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param modifyTime This parameter is the output parameter, + * and the create time of the asset as a int64_t is written to this variable. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetModifyTime(Data_Asset *asset, int64_t *modifyTime); + +/** + * @brief Obtains the size of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param size This parameter is the output parameter, + * and the size of the asset as a size_t is written to this variable. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset + * @since 11 + */ +int OH_Data_Asset_GetSize(Data_Asset *asset, size_t *size); + +/** + * @brief Obtains the status of the asset. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @param status This parameter is the output parameter, + * and the size of the status as a {@link Data_AssetStatus} is written to this variable. + * @return Returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset Data_AssetStatus. + * @since 11 + */ +int OH_Data_Asset_GetStatus(Data_Asset *asset, Data_AssetStatus *status); + +/** + * @brief Creates an {@link Data_Asset} instance. + * + * @return If the creation is successful, a pointer to the instance of the @link Data_Asset} structure is returned, + * otherwise NULL is returned. + * @see Data_Asset. + * @since 11 + */ +Data_Asset *OH_Data_Asset_CreateOne(); + +/** + * @brief Destroy the {@link Data_Asset} object and reclaim the memory occupied by the object. + * + * @param asset Represents a pointer to an {@link Data_Asset} instance. + * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset, OH_Rdb_ErrCode. + * @since 11 + */ +int OH_Data_Asset_DestroyOne(Data_Asset *asset); + +/** + * @brief Creates {@link Data_Asset} instances of given number. + * + * @param count Represents the count of {@link Data_Asset} to create. + * @return If the creation is successful, a pointer to the instance of the @link Data_Asset} structure is returned, + * otherwise NULL is returned. + * @see Data_Asset. + * @since 11 + */ +Data_Asset **OH_Data_Asset_CreateMultiple(uint32_t count); + +/** + * @brief Destroy the {@link Data_Asset} objects and reclaim the memory occupied by the objects. + * + * @param assets Represents a pointer to an {@link Data_Asset} instance. + * @param count Represents the count of {@link Data_Asset} to destroy. + * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see Data_Asset, OH_Rdb_ErrCode. + * @since 11 + */ +int OH_Data_Asset_DestroyMultiple(Data_Asset **assets, uint32_t count); +#ifdef __cplusplus +}; +#endif +#endif // DATA_ASSET_H diff --git a/relational_store/interfaces/ndk/include/oh_cursor.h b/relational_store/interfaces/ndk/include/oh_cursor.h index 165da158ee6c968130b3883150ac7f72b2200b0d..02e9549b3cf685eabbfbc5efebed5694821f8afe 100644 --- a/relational_store/interfaces/ndk/include/oh_cursor.h +++ b/relational_store/interfaces/ndk/include/oh_cursor.h @@ -40,6 +40,7 @@ #include #include #include +#include "data_asset.h" #ifdef __cplusplus extern "C" { #endif @@ -70,6 +71,18 @@ typedef enum OH_ColumnType { * Indicates the column type is BLOB. */ TYPE_BLOB, + /** + * Indicates the column type is {@link Data_Asset}. + * + * @since 11 + */ + TYPE_ASSET, + /** + * Indicates the column type is array of {@link Data_Asset}. + * + * @since 11 + */ + TYPE_ASSETS } OH_ColumnType; /** @@ -245,6 +258,33 @@ typedef struct OH_Cursor { * @since 10 */ int (*destroy)(OH_Cursor *cursor); + + /** + * @brief Function pointer. Obtains the value of the requested column as an {@link Data_Asset} instance. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as an {@link Data_Asset} instance is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 11 + */ + int (*getAsset)(OH_Cursor *cursor, int32_t columnIndex, Data_Asset *value); + + /** + * @brief Function pointer. Obtains the value of the requested column as an {@link Data_Asset} instance. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as an {@link Data_Asset} instance is written to this variable. + * @param length Indicates the length of the value. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 11 + */ + int (*getAssets)(OH_Cursor *cursor, int32_t columnIndex, Data_Asset **value, uint32_t *length); } OH_Cursor; #ifdef __cplusplus diff --git a/relational_store/interfaces/ndk/include/oh_values_bucket.h b/relational_store/interfaces/ndk/include/oh_values_bucket.h index e966956b68a49fc04e7adda371c2c57cd10ef29c..66a923e2609a10cd404b661515bf51f3b1763b07 100644 --- a/relational_store/interfaces/ndk/include/oh_values_bucket.h +++ b/relational_store/interfaces/ndk/include/oh_values_bucket.h @@ -38,6 +38,7 @@ */ #include +#include "data_asset.h" #ifdef __cplusplus extern "C" { #endif @@ -139,6 +140,30 @@ typedef struct OH_VBucket { int (*destroy)(OH_VBucket *bucket); } OH_VBucket; +/** + * @brief Put the {@link Data_Asset} * value to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the const {@link Data_Asset} * value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 11 + */ +int OH_VBucket_PutAsset(OH_VBucket *bucket, const char *field, Data_Asset *value); + +/** + * @brief Put the {@link Data_Asset} * value of given count to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the {@link Data_Asset} value of given count. + * @param count Indicates the count of value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 11 + */ +int OH_VBucket_PutAssets(OH_VBucket *bucket, const char *field, Data_Asset **value, uint32_t count); #ifdef __cplusplus }; #endif diff --git a/relational_store/interfaces/ndk/include/relational_store.h b/relational_store/interfaces/ndk/include/relational_store.h index 7b009ec34bb0f750e0d0d61a99ab534409a7f982..0377023a73a7f20e74a0b3fd2ac28f64b0ef6f6a 100644 --- a/relational_store/interfaces/ndk/include/relational_store.h +++ b/relational_store/interfaces/ndk/include/relational_store.h @@ -70,6 +70,30 @@ typedef enum OH_Rdb_SecurityLevel { S4 } OH_Rdb_SecurityLevel; +/** + * @brief Describe the security area of the database. + * + * @since 11 + */ +typedef enum Rdb_SecurityArea { + /** + * @brief Security Area 1. + */ + RDB_SECURITY_AREA_EL1 = 1, + /** + * @brief Security Area 2. + */ + RDB_SECURITY_AREA_EL2, + /** + * @brief Security Area 3. + */ + RDB_SECURITY_AREA_EL3, + /** + * @brief Security Area 4. + */ + RDB_SECURITY_AREA_EL4, +} Rdb_SecurityArea; + /** * @brief Manages relational database configurations. * @@ -105,6 +129,12 @@ typedef struct { * Indicates the security level {@link OH_Rdb_SecurityLevel} of the database. */ int securityLevel; + /** + * Indicates the security area {@link Rdb_SecurityArea} of the database. + * + * @since 11 + */ + int area; } OH_Rdb_Config; #pragma pack() @@ -343,6 +373,416 @@ int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version); */ int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version); +/** + * @brief Describes the distribution type of the tables. + * + * @since 11 + */ +typedef enum Rdb_DistributedType { + /** + * @brief Indicates the table is distributed among the devices. + */ + RDB_DISTRIBUTED_CLOUD +} Rdb_DistributedType; + +/** + * @brief Indicates version of {@link Rdb_DistributedConfig} + * + * @since 11 + */ +#define DISTRIBUTED_CONFIG_VERSION 1 +/** + * @brief Manages the distributed configuration of the table. + * + * @since 11 + */ +typedef struct Rdb_DistributedConfig { + /** + * The version used to uniquely identify the Rdb_DistributedConfig struct. + */ + int version; + /** + * Specifies whether the table auto syncs. + */ + bool isAutoSync; +} Rdb_DistributedConfig; + +/** + * @brief Set table to be distributed table. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param tables Indicates the table names you want to set. + * @param count Indicates the count of tables you want to set. + * @param type Indicates the distributed type {@link Rdb_DistributedType}. + * @param config Indicates the distributed config of the tables. For details, see {@link Rdb_DistributedConfig}. + * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store. + * @see Rdb_DistributedConfig. + * @since 11 + */ +int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, + const Rdb_DistributedConfig *config); + +/** + * @brief Set table to be distributed table. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param tableName Indicates the name of the table to check. + * @param columnName Indicates the name of the column corresponding to the primary key. + * If the table has no primary key , please pass in "rowid". + * @param values Indicates the primary keys of the rows to check. + * If the table has no primary key , please pass in the row-ids of the rows to check. + * @return If the operation is successful, a pointer to the instance of the @link OH_Cursor} structure is returned. + * There are two columns, "data_key" and "timestamp". Otherwise NULL is returned. + * @see OH_Rdb_Store. + * @see OH_VObject. + * @see OH_Cursor. + * @since 11 + */ +OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, + OH_VObject *values); + +/** + * @brief Describes the change type. + * + * @since 11 + */ +typedef enum Rdb_ChangeType { + /** + * @brief Means the change type is data change. + */ + RDB_DATA_CHANGE, + /** + * @brief Means the change type is asset change. + */ + RDB_ASSET_CHANGE +} Rdb_ChangeType; + +/** + * @brief Describes the primary keys or row-ids of changed rows. + * + * @since 11 + */ +typedef struct Rdb_KeyInfo { + /** + * Indicates the count of the primary keys or row-ids. + */ + int count; + + /** + * Indicates data type {@link OH_ColumnType} of the key. + */ + int type; + + /** + * Indicates the data of the key info. + */ + union Rdb_KeyData { + /** + * Indicates uint64_t type of the data. + */ + uint64_t integer; + + /** + * Indicates double type of the data. + */ + double real; + + /** + * Indicates const char * type of the data. + */ + const char *text; + } *data; +} Rdb_KeyInfo; + +/** + * @brief Indicates version of {@link Rdb_ChangeInfo} + * + * @since 11 + */ +#define DISTRIBUTED_CHANGE_INFO_VERSION 1 + +/** + * @brief Describes the notify info of data change. + * + * @since 11 + */ +typedef struct Rdb_ChangeInfo { + /** + * The version used to uniquely identify the Rdb_ChangeInfo struct. + */ + int version; + + /** + * The name of changed table. + */ + const char *tableName; + + /** + * The {@link Rdb_ChangeType} of changed table. + */ + int ChangeType; + + /** + * The {@link Rdb_KeyInfo} of inserted rows. + */ + Rdb_KeyInfo inserted; + + /** + * The {@link Rdb_KeyInfo} of updated rows. + */ + Rdb_KeyInfo updated; + + /** + * The {@link Rdb_KeyInfo} of deleted rows. + */ + Rdb_KeyInfo deleted; +} Rdb_ChangeInfo; + +/** + * @brief Indicates the subscribe type. + * + * @since 11 + */ +typedef enum Rdb_SubscribeType { + /** + * @brief Subscription to cloud data changes. + */ + RDB_SUBSCRIBE_TYPE_CLOUD, + + /** + * @brief Subscription to cloud data change details. + */ + RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS, +} Rdb_SubscribeType; + +/** + * @brief Indicates the database synchronization mode. + * + * @since 11 + */ +typedef enum Rdb_SyncMode { + /** + * @brief Indicates that data is synchronized from the end with the closest modification time + * to the end with a more distant modification time. + */ + RDB_SYNC_MODE_TIME_FIRST, + /** + * @brief Indicates that data is synchronized from local to cloud. + */ + RDB_SYNC_MODE_NATIVE_FIRST, + /** + * @brief Indicates that data is synchronized from cloud to local. + */ + RDB_SYNC_MODE_CLOUD_FIRST +} Rdb_SyncMode; + +/** + * @brief Describes the statistic of the cloud sync process. + * + * @since 11 + */ +typedef struct Rdb_Statistic { + /** + * Describes the total number of data to sync. + */ + int total; + + /** + * Describes the number of successfully synced data. + */ + int successful; + + /** + * Describes the number of data failed to sync. + */ + int failed; + + /** + * Describes the number of data remained to sync. + */ + int remained; +} Rdb_Statistic; + +/** + * @brief Describes the {@link Rdb_Statistic} details of the table. + * + * @since 11 + */ +typedef struct Rdb_TableDetails { + /** + * Indicates the name of changed table. + */ + const char *table; + + /** + * Describes the {@link Rdb_Statistic} details of the upload process. + */ + Rdb_Statistic upload; + + /** + * Describes the {@link Rdb_Statistic} details of the download process. + */ + Rdb_Statistic download; +} Rdb_TableDetails; + +/** + * The cloud sync progress + * + * @since 11 + */ +typedef enum Rdb_Progress { + /** + * @brief Means the sync process begin. + */ + RDB_SYNC_BEGIN, + + /** + * @brief Means the sync process is in progress + */ + RDB_SYNC_IN_PROGRESS, + + /** + * @brief Means the sync process is finished + */ + RDB_SYNC_FINISH +} Rdb_Progress; + +/** + * Describes the status of cloud sync progress. + * + * @since 11 + */ +typedef enum Rdb_ProgressCode { + /** + * @brief Means the status of progress is success. + */ + RDB_SUCCESS, + + /** + * @brief Means the progress meets unknown error. + */ + RDB_UNKNOWN_ERROR, + + /** + * @brief Means the progress meets network error. + */ + RDB_NETWORK_ERROR, + + /** + * @brief Means cloud is disabled. + */ + RDB_CLOUD_DISABLED, + + /** + * @brief Means the progress is locked by others. + */ + RDB_LOCKED_BY_OTHERS, + + /** + * @brief Means the record exceeds the limit. + */ + RDB_RECORD_LIMIT_EXCEEDED, + + /** + * Means the cloud has no space for the asset. + */ + RDB_NO_SPACE_FOR_ASSET +} Rdb_ProgressCode; + +/** + * @brief Indicates version of {@link Rdb_ProgressDetails} + * + * @since 11 + */ +#define DISTRIBUTED_PROGRESS_DETAIL_VERSION 1 + +/** + * @brief Describes detail of the cloud sync progress. + * + * @since 11 + */ +typedef struct Rdb_ProgressDetails { + /** + * The version used to uniquely identify the Rdb_ProgressDetails struct. + */ + int version; + + /** + * Describes the status of data sync progress. Defined in {@link Rdb_Progress}. + */ + int schedule; + + /** + * Describes the code of data sync progress. Defined in {@link Rdb_ProgressCode}. + */ + int code; + + /** + * Describes the length of changed tables in data sync progress. + */ + int32_t tableLength; +} Rdb_ProgressDetails; + +/** + * @brief Get table details from progress details. + * + * @param progress Represents a pointer to an {@link Rdb_ProgressDetails} instance. + * @param version Indicates the version of current {@link Rdb_ProgressDetails}. + * @return If the operation is successful, a pointer to the instance of the @link Rdb_TableDetails} structure is returned. + * Otherwise NULL is returned. + * @see Rdb_ProgressDetails + * @see Rdb_TableDetails + * @since 11 + */ +Rdb_TableDetails *OH_Rdb_GetTableDetails(Rdb_ProgressDetails *progress, int32_t version); + +/** + * @brief The callback function of sync. + * + * @param progressDetails The details of the sync progress. + * @see Rdb_ProgressDetails. + * @since 11 + */ +typedef void (*Rdb_SyncCallback)(Rdb_ProgressDetails *progressDetails); + +/** + * @brief Sync data to cloud. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param mode Represents the {@link Rdb_SyncMode} of sync progress. + * @param tables Indicates the names of tables to sync. + * @param count The count of tables to sync. If value equals 0, sync all tables of the store. + * @param callback The {@link Rdb_SyncCallback} of cloud sync progress. + * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store. + * @see Rdb_SyncCallback. + * @since 11 + */ +int OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, + Rdb_SyncCallback *callback); + +/** +* @brief Subscribes to the automatic synchronization progress of an RDB store. +* A callback will be invoked when there is a notification of the automatic synchronization progress. +* +* @param store Indicates the pointer to the target {@Link OH_Rdb_Store} instance. +* @param Indicates the callback invoked to return the automatic synchronization progress. +* @see OH_Rdb_Store. +* @since 11 +*/ +int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, Rdb_SyncCallback *progress); + +/** +* @brief Unsubscribes from the automatic synchronziation progress of an RDB store. +* +* @param store Indicates the pointer to the target {@Link OH_Rdb_Store} instance. +* @param progress Indicates the callback for the automatic synchornizaiton progress. +* If it is a null pointer, all callbacks for the automatic synchornizaiton progress will be unregistered. +* @see OH_Rdb_Store. +* @since 11 +*/ +int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, Rdb_SyncCallback *progress); #ifdef __cplusplus }; #endif diff --git a/relational_store/interfaces/ndk/libnative_rdb.ndk.json b/relational_store/interfaces/ndk/libnative_rdb.ndk.json index 84901bb5404a0d1dd5886ce860473a2756d7e697..190d3cbb00fce469dd7a1261f1c51bb4bfc7ebbe 100644 --- a/relational_store/interfaces/ndk/libnative_rdb.ndk.json +++ b/relational_store/interfaces/ndk/libnative_rdb.ndk.json @@ -17,5 +17,29 @@ {"name":"OH_Rdb_Backup" }, {"name":"OH_Rdb_Restore"}, {"name":"OH_Rdb_GetVersion"}, - {"name":"OH_Rdb_SetVersion"} + {"name":"OH_Rdb_SetVersion"}, + {"name":"OH_Rdb_SetDistributedTables"}, + {"name":"OH_Rdb_FindModifyTime"}, + {"name":"OH_Rdb_GetTableDetails"}, + {"name":"OH_Rdb_CloudSync"}, + {"name":"OH_VBucket_PutAsset"}, + {"name":"OH_VBucket_PutAssets"}, + {"name":"OH_Data_Asset_SetName"}, + {"name":"OH_Data_Asset_SetUri"}, + {"name":"OH_Data_Asset_SetPath"}, + {"name":"OH_Data_Asset_SetCreateTime"}, + {"name":"OH_Data_Asset_SetModifyTime"}, + {"name":"OH_Data_Asset_SetSize"}, + {"name":"OH_Data_Asset_SetStatus"}, + {"name":"OH_Data_Asset_GetName"}, + {"name":"OH_Data_Asset_GetUri"}, + {"name":"OH_Data_Asset_GetPath"}, + {"name":"OH_Data_Asset_GetCreateTime"}, + {"name":"OH_Data_Asset_GetModifyTime"}, + {"name":"OH_Data_Asset_GetSize"}, + {"name":"OH_Data_Asset_GetStatus"}, + {"name":"OH_Data_Asset_CreateOne"}, + {"name":"OH_Data_Asset_DestroyOne"}, + {"name":"OH_Data_Asset_CreateMultiple"}, + {"name":"OH_Data_Asset_DestroyMultiple"} ] \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/BUILD.gn b/relational_store/interfaces/ndk/src/BUILD.gn index a62b56bd17f798dc8acfbf34f3a6f17e76f64d3f..6ecfc9763b53d95b9d0aa152a7a0ddb207ac5692 100644 --- a/relational_store/interfaces/ndk/src/BUILD.gn +++ b/relational_store/interfaces/ndk/src/BUILD.gn @@ -17,10 +17,12 @@ import("//foundation/distributeddatamgr/relational_store/relational_store.gni") ohos_shared_library("native_rdb_ndk") { include_dirs = [ "../include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_native_path}/rdb/include", ] sources = [ + "relational_asset.cpp", "relational_cursor.cpp", "relational_predicates.cpp", "relational_predicates_objects.cpp", diff --git a/relational_store/interfaces/ndk/src/relational_asset.cpp b/relational_store/interfaces/ndk/src/relational_asset.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c88741d44b32670504d99f9c5b44bfa8a71dc96a --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_asset.cpp @@ -0,0 +1,224 @@ +/* +* 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 "relational_asset.h" + +#include "logger.h" +#include "relational_store_error_code.h" +#include "securec.h" +#include + +using namespace OHOS::RdbNdk; +constexpr int ASSET_TRANSFORM_BASE = 10; +int OH_Data_Asset_SetName(Data_Asset *asset, const char *name) +{ + if (asset == nullptr || name == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + asset->asset_.name = name; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetUri(Data_Asset *asset, const char *uri) +{ + if (asset == nullptr || uri == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.uri = uri; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetPath(Data_Asset *asset, const char *path) +{ + if (asset == nullptr || path == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.path = path; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetCreateTime(Data_Asset *asset, int64_t createTime) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.createTime = std::to_string(createTime); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetModifyTime(Data_Asset *asset, int64_t modifyTime) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.modifyTime = std::to_string(modifyTime); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetSize(Data_Asset *asset, size_t size) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.size = std::to_string(size); + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_SetStatus(Data_Asset *asset, Data_AssetStatus status) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + asset->asset_.status = status; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetName(Data_Asset *asset, char *name, size_t *length) +{ + size_t nameLength = 0; + if (asset == nullptr || (nameLength = asset->asset_.name.size()) >= *length) { + LOG_ERROR("Asset get name error: asset is NULL ? %{public}d and length is too small ? %{public}d.", + (asset == nullptr), (nameLength >= *length)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + errno_t result = strcpy_s(name, *length, asset->asset_.name.c_str()); + if (result != EOK) { + LOG_ERROR("strcpy_s failed, result is %{public}d", result); + return OH_Rdb_ErrCode::RDB_ERR; + } + *length = nameLength; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetUri(Data_Asset *asset, char *uri, size_t *length) +{ + size_t uriLength = 0; + if (asset == nullptr || (uriLength = asset->asset_.uri.size()) >= *length) { + LOG_ERROR("Asset get uri error: asset is NULL ? %{public}d and length is too small ? %{public}d.", + (asset == nullptr), (uriLength >= *length)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + errno_t result = strcpy_s(uri, *length, asset->asset_.uri.c_str()); + if (result != EOK) { + LOG_ERROR("strcpy_s failed, result is %{public}d", result); + return OH_Rdb_ErrCode::RDB_ERR; + } + *length = uriLength; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetPath(Data_Asset *asset, char *path, size_t *length) +{ + size_t pathLength = 0; + if (asset == nullptr || (pathLength = asset->asset_.path.size()) >= *length) { + LOG_ERROR("Asset get path error: asset is NULL ? %{public}d and length is too small ? %{public}d.", + (asset == nullptr), (pathLength >= *length)); + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + errno_t result = strcpy_s(path, *length, asset->asset_.path.c_str()); + if (result != EOK) { + LOG_ERROR("strcpy_s failed, result is %{public}d", result); + return OH_Rdb_ErrCode::RDB_ERR; + } + *length = pathLength; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetCreateTime(Data_Asset *asset, int64_t *createTime) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + char *endPtr; + *createTime = strtol(asset->asset_.createTime.c_str(), &endPtr, ASSET_TRANSFORM_BASE); + if (*endPtr != '\0') { + LOG_ERROR("GetCreateTime failed"); + return OH_Rdb_ErrCode::RDB_ERR; + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetModifyTime(Data_Asset *asset, int64_t *modifyTime) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + char *endPtr; + *modifyTime = strtol(asset->asset_.modifyTime.c_str(), &endPtr, ASSET_TRANSFORM_BASE); + if (*endPtr != '\0') { + LOG_ERROR("GetModifyTime failed"); + return OH_Rdb_ErrCode::RDB_ERR; + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetSize(Data_Asset *asset, size_t *size) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + char *endPtr; + *size = strtol(asset->asset_.size.c_str(), &endPtr, ASSET_TRANSFORM_BASE); + if (*endPtr != '\0') { + LOG_ERROR("GetModifyTime failed"); + return OH_Rdb_ErrCode::RDB_ERR; + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_Data_Asset_GetStatus(Data_Asset *asset, Data_AssetStatus *status) +{ + if (asset == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + *status = static_cast(asset->asset_.status); + return OH_Rdb_ErrCode::RDB_OK; +} + +Data_Asset *OH_Data_Asset_CreateOne() +{ + return new (std::nothrow) Data_Asset(); +} + +int OH_Data_Asset_DestroyOne(Data_Asset *asset) +{ + delete asset; + asset = nullptr; + return OH_Rdb_ErrCode::RDB_OK; +} + +Data_Asset **OH_Data_Asset_CreateMultiple(uint32_t count) +{ + auto assets = new Data_Asset *[count]; + for (int i = 0; i < count; ++i) { + assets[i] = new Data_Asset(); + } + return assets; +} + +int OH_Data_Asset_DestroyMultiple(Data_Asset **assets, uint32_t count) +{ + for (int i = 0; i < count; ++i) { + delete assets[i]; + } + delete[] assets; + assets = nullptr; + return OH_Rdb_ErrCode::RDB_OK; +} diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp b/relational_store/interfaces/ndk/src/relational_asset.h similarity index 65% rename from datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp rename to relational_store/interfaces/ndk/src/relational_asset.h index cbaef55d2b7989f9c60e77db7c9a534be5848791..5bf7ff2f522d94ebe83ef19c2ed91e3d6769ebd5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp +++ b/relational_store/interfaces/ndk/src/relational_asset.h @@ -12,9 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef RELATIONAL_ASSET_IMPL_H +#define RELATIONAL_ASSET_IMPL_H -#include "db_constant.h" +#include "asset_value.h" +#include "data_asset.h" +using AssetValue = OHOS::NativeRdb::AssetValue; +constexpr int32_t DATA_ASSET_V0 = 10002451; +struct Data_Asset { + int32_t cid = DATA_ASSET_V0; + AssetValue asset_; +}; -namespace DocumentDB { -const std::string DBConstant::COLL_PREFIX = "GRD_COLL_"; -} // namespace DocumentDB \ No newline at end of file +#endif // RELATIONAL_ASSET_IMPL_H diff --git a/relational_store/interfaces/ndk/src/relational_cursor.cpp b/relational_store/interfaces/ndk/src/relational_cursor.cpp index 97130b76ee40be348f892a581b376bbe5bb8ef9a..80a8418a77cdae8b2ae8c007df431c9e29ea7d26 100644 --- a/relational_store/interfaces/ndk/src/relational_cursor.cpp +++ b/relational_store/interfaces/ndk/src/relational_cursor.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ +#include "relational_cursor.h" + #include #include #include @@ -20,9 +22,9 @@ #include "logger.h" #include "oh_cursor.h" -#include "relational_cursor.h" -#include "relational_store_error_code.h" #include "rdb_errno.h" +#include "relational_asset.h" +#include "relational_store_error_code.h" #include "securec.h" namespace OHOS { @@ -30,7 +32,7 @@ namespace RdbNdk { int RelationalCursor::GetColumnCount(OH_Cursor *cursor, int *count) { auto self = GetSelf(cursor); - if (self == nullptr || count == nullptr) { + if (self == nullptr || count == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetColumnCount(*count); @@ -39,7 +41,7 @@ int RelationalCursor::GetColumnCount(OH_Cursor *cursor, int *count) int RelationalCursor::GetColumnType(OH_Cursor *cursor, int32_t columnIndex, OH_ColumnType *columnType) { auto self = GetSelf(cursor); - if (self == nullptr || columnType == nullptr || columnIndex < 0) { + if (self == nullptr || columnType == nullptr || columnIndex < 0 || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } OHOS::NativeRdb::ColumnType type; @@ -51,7 +53,7 @@ int RelationalCursor::GetColumnType(OH_Cursor *cursor, int32_t columnIndex, OH_C int RelationalCursor::GetColumnIndex(OH_Cursor *cursor, const char *name, int *columnIndex) { auto self = GetSelf(cursor); - if (self == nullptr || name == nullptr || columnIndex == nullptr) { + if (self == nullptr || name == nullptr || columnIndex == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetColumnIndex(name, *columnIndex); @@ -60,7 +62,7 @@ int RelationalCursor::GetColumnIndex(OH_Cursor *cursor, const char *name, int *c int RelationalCursor::GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char *name, int length) { auto self = GetSelf(cursor); - if (self == nullptr || name == nullptr || length <= 0) { + if (self == nullptr || name == nullptr || length <= 0 || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } std::string str; @@ -79,7 +81,7 @@ int RelationalCursor::GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char int RelationalCursor::GetRowCount(OH_Cursor *cursor, int *count) { auto self = GetSelf(cursor); - if (self == nullptr || count == nullptr) { + if (self == nullptr || count == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetRowCount(*count); @@ -88,7 +90,7 @@ int RelationalCursor::GetRowCount(OH_Cursor *cursor, int *count) int RelationalCursor::GoToNextRow(OH_Cursor *cursor) { auto self = GetSelf(cursor); - if (self == nullptr) { + if (self == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GoToNextRow(); @@ -97,7 +99,7 @@ int RelationalCursor::GoToNextRow(OH_Cursor *cursor) int RelationalCursor::GetSize(OH_Cursor *cursor, int32_t columnIndex, size_t *size) { auto self = GetSelf(cursor); - if (self == nullptr || size == nullptr) { + if (self == nullptr || size == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetSize(columnIndex, *size); @@ -106,7 +108,7 @@ int RelationalCursor::GetSize(OH_Cursor *cursor, int32_t columnIndex, size_t *si int RelationalCursor::GetText(OH_Cursor *cursor, int32_t columnIndex, char *value, int length) { auto self = GetSelf(cursor); - if (self == nullptr || value == nullptr || length <= 0) { + if (self == nullptr || value == nullptr || length <= 0 || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } std::string str; @@ -125,7 +127,7 @@ int RelationalCursor::GetText(OH_Cursor *cursor, int32_t columnIndex, char *valu int RelationalCursor::GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t *value) { auto self = GetSelf(cursor); - if (self == nullptr || value == nullptr) { + if (self == nullptr || value == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetLong(columnIndex, *value); @@ -134,7 +136,7 @@ int RelationalCursor::GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t * int RelationalCursor::GetReal(OH_Cursor *cursor, int32_t columnIndex, double *value) { auto self = GetSelf(cursor); - if (self == nullptr || value == nullptr) { + if (self == nullptr || value == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->GetDouble(columnIndex, *value); @@ -143,7 +145,7 @@ int RelationalCursor::GetReal(OH_Cursor *cursor, int32_t columnIndex, double *va int RelationalCursor::GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length) { auto self = GetSelf(cursor); - if (self == nullptr || value == nullptr || length <= 0) { + if (self == nullptr || value == nullptr || length <= 0 || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } std::vector vec; @@ -159,10 +161,56 @@ int RelationalCursor::GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned c return OH_Rdb_ErrCode::RDB_OK; } +int RelationalCursor::GetAsset(OH_Cursor *cursor, int32_t columnIndex, Data_Asset *value) +{ + auto self = GetSelf(cursor); + if (self == nullptr || self->resultSet_ == nullptr || value == nullptr || value->cid != DATA_ASSET_V0 || + columnIndex < 0) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + NativeRdb::AssetValue asset; + auto errCode = self->resultSet_->GetAsset(columnIndex, asset); + if (errCode != OHOS::NativeRdb::E_OK) { + return errCode; + } + value->cid = DATA_ASSET_V0; + value->asset_ = asset; + return errCode; +} + +int RelationalCursor::GetAssets(OH_Cursor *cursor, int32_t columnIndex, Data_Asset **value, uint32_t *length) +{ + auto self = GetSelf(cursor); + if (self == nullptr || self->resultSet_ == nullptr || length == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + std::vector assets; + auto errCode = self->resultSet_->GetAssets(columnIndex, assets); + if (errCode != OHOS::NativeRdb::E_OK) { + return errCode; + } + uint32_t inputLength = *length; + *length = assets.size(); + if (value == nullptr) { + return OH_Rdb_ErrCode::RDB_OK; + } + if (*length != inputLength) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + for (int i = 0; i < *length; ++i) { + if (value[i] == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + value[i]->cid = DATA_ASSET_V0; + value[i]->asset_ = assets[i]; + } + return errCode; +} + int RelationalCursor::IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNull) { auto self = GetSelf(cursor); - if (self == nullptr || isNull == nullptr) { + if (self == nullptr || isNull == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return self->resultSet_->IsColumnNull(columnIndex, *isNull); @@ -171,7 +219,7 @@ int RelationalCursor::IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNul int RelationalCursor::Destroy(OH_Cursor *cursor) { auto self = GetSelf(cursor); - if (self == nullptr) { + if (self == nullptr || self->resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } int errCode = self->resultSet_->Close(); @@ -200,6 +248,8 @@ RelationalCursor::RelationalCursor(std::shared_ptr r getBlob = GetBlob; isNull = IsNull; destroy = Destroy; + getAsset = GetAsset; + getAssets = GetAssets; } RelationalCursor *RelationalCursor::GetSelf(OH_Cursor *cursor) @@ -211,4 +261,4 @@ RelationalCursor *RelationalCursor::GetSelf(OH_Cursor *cursor) return static_cast(cursor); } } // namespace RdbNdk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/relational_store/interfaces/ndk/src/relational_cursor.h b/relational_store/interfaces/ndk/src/relational_cursor.h index 6f556a958f32f90d30c09b402b2223dab226c939..1da5bd2c7644546dd4be979030064629fecf0b57 100644 --- a/relational_store/interfaces/ndk/src/relational_cursor.h +++ b/relational_store/interfaces/ndk/src/relational_cursor.h @@ -38,6 +38,8 @@ private: static int GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t *value); static int GetReal(OH_Cursor *cursor, int32_t columnIndex, double *value); static int GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length); + static int GetAsset(OH_Cursor *cursor, int32_t columnIndex, Data_Asset *value); + static int GetAssets(OH_Cursor *cursor, int32_t columnIndex, Data_Asset **value, uint32_t *length); static int IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNull); static int Destroy(OH_Cursor *cursor); static RelationalCursor *GetSelf(OH_Cursor *cursor); diff --git a/relational_store/interfaces/ndk/src/relational_store.cpp b/relational_store/interfaces/ndk/src/relational_store.cpp index f48e84ae014eb4e356e83f56ffdc047cba86b189..b4d7d9ac158253f8672a53faf5593a209535ec26 100644 --- a/relational_store/interfaces/ndk/src/relational_store.cpp +++ b/relational_store/interfaces/ndk/src/relational_store.cpp @@ -13,21 +13,32 @@ * limitations under the License. */ +#include "relational_store.h" + #include "logger.h" +#include "raw_data_parser.h" #include "rdb_errno.h" #include "rdb_helper.h" #include "rdb_predicates.h" #include "rdb_sql_utils.h" #include "relational_cursor.h" -#include "relational_store_error_code.h" #include "relational_predicates.h" -#include "relational_store_impl.h" #include "relational_predicates_objects.h" +#include "relational_store_error_code.h" +#include "relational_store_impl.h" #include "relational_values_bucket.h" #include "sqlite_global_config.h" +#include "sys/stat.h" +#include "unistd.h" using namespace OHOS::RdbNdk; +using namespace OHOS::DistributedRdb; constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class. +constexpr int RDB_DISTRIBUTED_CONFIG_V0 = 1; +constexpr int RDB_PROGRESS_DETAILS_V0 = 1; +constexpr int RDB_TABLE_DETAILS_V0 = 1; +constexpr int RDB_CONFIG_SIZE_V0 = 41; +constexpr int RDB_CONFIG_SIZE_V1 = 45; OH_VObject *OH_Rdb_CreateValueObject() { return new (std::nothrow) RelationalPredicatesObjects(); @@ -51,6 +62,21 @@ OHOS::RdbNdk::RelationalStore::RelationalStore(std::shared_ptr(-1); + } +} + class MainOpenCallback : public OHOS::NativeRdb::RdbOpenCallback { public: int OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override; @@ -78,15 +104,15 @@ RelationalStore *GetRelationalStore(OH_Rdb_Store *store) OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) { - if (config == nullptr || config->selfSize != sizeof(OH_Rdb_Config) || errCode == nullptr) { + if (config == nullptr || config->selfSize > RDB_CONFIG_SIZE_V1 || errCode == nullptr) { LOG_ERROR("Parameters set error:config is NULL ? %{public}d and config size is %{public}zu or " "errCode is NULL ? %{public}d ", (config == nullptr), sizeof(OH_Rdb_Config), (errCode == nullptr)); return nullptr; } - std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, - config->storeName, *errCode); + std::string realPath = + OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode); if (*errCode != 0) { LOG_ERROR("Get database path failed, ret %{public}d ", *errCode); return nullptr; @@ -94,6 +120,9 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath); rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); rdbStoreConfig.SetEncryptStatus(config->isEncrypt); + if (config->selfSize > RDB_CONFIG_SIZE_V0) { + rdbStoreConfig.SetArea(config->area); + } if (config->bundleName != nullptr) { rdbStoreConfig.SetBundleName(config->bundleName); } @@ -126,8 +155,8 @@ int OH_Rdb_DeleteStore(const OH_Rdb_Config *config) return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } int errCode = OHOS::NativeRdb::E_OK; - std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, - config->storeName, errCode); + std::string realPath = + OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode); if (errCode != OHOS::NativeRdb::E_OK) { return errCode; } @@ -278,4 +307,155 @@ int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version) return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } return rdbStore->GetStore()->SetVersion(version); -} \ No newline at end of file +} + +std::pair Convert(const Rdb_DistributedConfig *config) +{ + if (config->version < RDB_DISTRIBUTED_CONFIG_V0) { + return { -1, {} }; + } + switch (config->version) { + case RDB_DISTRIBUTED_CONFIG_V0: + return { 0, DistributedConfig{ .autoSync = config->isAutoSync } }; + default: + return { -1, {} }; + } +} + +int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, + const Rdb_DistributedConfig *config) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || type != Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + auto ret = Convert(config); + if (ret.first < 0) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + std::vector tableNames; + tableNames.reserve(count); + for (uint32_t i = 0; i < count; i++) { + tableNames.emplace_back(tables[i]); + } + return rdbStore->GetStore()->SetDistributedTables(tableNames, DistributedTableType::DISTRIBUTED_CLOUD, ret.second); +} + +OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values) +{ + auto rdbStore = GetRelationalStore(store); + auto selfObjects = RelationalPredicatesObjects::GetSelf(values); + if (rdbStore == nullptr || selfObjects == nullptr || tableName == nullptr) { + return nullptr; + } + std::vector objects = selfObjects->Get(); + std::vector keys; + keys.reserve(objects.size()); + for (const auto &object : objects) { + OHOS::NativeRdb::RdbStore::PRIKey priKey; + OHOS::NativeRdb::RawDataParser::Convert(object.value, priKey); + keys.push_back(priKey); + } + auto results = rdbStore->GetStore()->GetModifyTime(tableName, columnName, keys); + return new (std::nothrow) RelationalCursor(std::move(results)); +} + +struct RelationalTableDetailsV0 : public Rdb_TableDetails { +}; + +struct RelationalProgressDetails : public Rdb_ProgressDetails { + TableDetails tableDetails_; + Rdb_TableDetails *details_ = nullptr; + int curVersion_ = -1; + explicit RelationalProgressDetails(const ProgressDetail &detail); + Rdb_TableDetails *GetTableDetails(int paraVersion); + void DestroyTableDetails(); +}; + +void RelationalProgressDetails::DestroyTableDetails() +{ + delete[] details_; +} + +RelationalProgressDetails::RelationalProgressDetails(const ProgressDetail &detail) : Rdb_ProgressDetails() +{ + version = RDB_PROGRESS_DETAILS_V0; + schedule = detail.progress; + code = detail.code; + tableLength = (int32_t)detail.details.size(); + tableDetails_ = detail.details; +} + +Rdb_TableDetails *RelationalProgressDetails::GetTableDetails(int paraVersion) +{ + if (curVersion_ == paraVersion) { + return details_; + } + DestroyTableDetails(); + switch (paraVersion) { + case RDB_TABLE_DETAILS_V0: { + details_ = new RelationalTableDetailsV0[tableLength + 1]; + int index = 0; + for (const auto &pair : tableDetails_) { + details_[index].table = pair.first.c_str(); + details_[index].upload = Rdb_Statistic{ + .total = (int)pair.second.upload.total, + .successful = (int)pair.second.upload.success, + .failed = (int)pair.second.upload.failed, + .remained = (int)pair.second.upload.untreated, + }; + details_[index].download = Rdb_Statistic{ + .total = (int)pair.second.download.total, + .successful = (int)pair.second.download.success, + .failed = (int)pair.second.download.failed, + .remained = (int)pair.second.download.untreated, + }; + index++; + } + curVersion_ = paraVersion; + return details_; + } + default: + return nullptr; + } +} + +std::pair GetDetails(Rdb_ProgressDetails *progress, int32_t version) +{ + switch (version) { + case RDB_PROGRESS_DETAILS_V0: + return { 0, (RelationalProgressDetails *)progress }; + default: + return { -1, {} }; + } +} + +Rdb_TableDetails *OH_Rdb_GetTableDetails(Rdb_ProgressDetails *progress, int32_t version) +{ + auto pair = GetDetails(progress, version); + if (pair.first == -1) { + return nullptr; + } + return pair.second->GetTableDetails(version); +} + +int OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, + Rdb_SyncCallback *callback) +{ + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || mode < RDB_SYNC_MODE_TIME_FIRST || mode > RDB_SYNC_MODE_CLOUD_FIRST || + callback == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + SyncOption syncOption{ .mode = NDKUtils::TransformMode(mode), .isBlock = false }; + std::vector tableNames; + for (uint32_t i = 0; i < count; ++i) { + tableNames.emplace_back(tables[i]); + } + auto progressCallback = [&callback](Details &&details) { + RelationalProgressDetails progressDetails = RelationalProgressDetails(details.begin()->second); + (*callback)(&progressDetails); + progressDetails.DestroyTableDetails(); + }; + return rdbStore->GetStore()->Sync(syncOption, tableNames, progressCallback); +} diff --git a/relational_store/interfaces/ndk/src/relational_store_impl.h b/relational_store/interfaces/ndk/src/relational_store_impl.h index 4d02f1a393352f9144035680634c87f7c6589d64..34b3936953f1b4eafbb3d89803e13ab4cd7e41e4 100644 --- a/relational_store/interfaces/ndk/src/relational_store_impl.h +++ b/relational_store/interfaces/ndk/src/relational_store_impl.h @@ -16,14 +16,16 @@ #ifndef RELATIONAL_STORE_IMPL_H #define RELATIONAL_STORE_IMPL_H +#include #include -#include "rdb_store.h" #include "oh_predicates.h" +#include "rdb_store.h" #include "relational_store.h" namespace OHOS { namespace RdbNdk { + class RelationalStore : public OH_Rdb_Store { public: explicit RelationalStore(std::shared_ptr store); @@ -35,6 +37,11 @@ public: private: std::shared_ptr store_; }; + +class NDKUtils { +public: + static OHOS::DistributedRdb::SyncMode TransformMode(Rdb_SyncMode &mode); +}; } // namespace RdbNdk } // namespace OHOS #endif // RELATIONAL_STORE_IMPL_H diff --git a/relational_store/interfaces/ndk/src/relational_values_bucket.cpp b/relational_store/interfaces/ndk/src/relational_values_bucket.cpp index a7b351efbb506189372fa38e55da5bac2e23f195..4210a3f347fcea67aa82802b232c59180d94edc4 100644 --- a/relational_store/interfaces/ndk/src/relational_values_bucket.cpp +++ b/relational_store/interfaces/ndk/src/relational_values_bucket.cpp @@ -13,14 +13,16 @@ * limitations under the License. */ +#include "relational_values_bucket.h" + #include #include "logger.h" #include "oh_values_bucket.h" +#include "relational_asset.h" #include "relational_store_error_code.h" -#include "relational_values_bucket.h" -#include "value_object.h" #include "securec.h" +#include "value_object.h" namespace OHOS { namespace RdbNdk { @@ -119,3 +121,35 @@ int RelationalValuesBucket::PutValueObject(OH_VBucket *bucket, const char *field } } // namespace RdbNdk } // namespace OHOS + +using namespace OHOS::RdbNdk; +using namespace OHOS::NativeRdb; +int OH_VBucket_PutAsset(OH_VBucket *bucket, const char *field, Data_Asset *value) +{ + auto self = RelationalValuesBucket::GetSelf(bucket); + if (self == nullptr || field == nullptr || value == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + self->Get().Put(field, OHOS::NativeRdb::ValueObject(value->asset_)); + self->capability++; + return OH_Rdb_ErrCode::RDB_OK; +} + +int OH_VBucket_PutAssets(OH_VBucket *bucket, const char *field, Data_Asset **value, uint32_t count) +{ + auto self = RelationalValuesBucket::GetSelf(bucket); + if (self == nullptr || field == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + std::vector assets; + for (int i = 0; i < count; i++) { + if (value[i] == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + assets.emplace_back(value[i]->asset_); + } + self->Get().Put(field, ValueObject(assets)); + self->capability++; + + return OH_Rdb_ErrCode::RDB_OK; +} diff --git a/relational_store/relational_store.gni b/relational_store/relational_store.gni index f5718158acc1a2b0864e0911ec0c6b550bc8b490..57eb7a2835f48e4e18a338ec06bedee8e00fff48 100644 --- a/relational_store/relational_store.gni +++ b/relational_store/relational_store.gni @@ -43,5 +43,9 @@ ipc_path = "//foundation/communication/ipc/interfaces/innerkits" kvstore_path = "//foundation/distributeddatamgr/kv_store/frameworks" +kvstore_interface_path = "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include" + distributedfile_path = "//foundation/filemanagement/file_api/interfaces/kits/js/src" + +sdk_c_path = "//interface/sdk_c/distributeddatamgr" diff --git a/relational_store/test/js/rdb/unittest/src/RdbstoreEncryptionJsunit.test.js b/relational_store/test/js/rdb/unittest/src/RdbstoreEncryptionJsunit.test.js index a9fedda8a9325d52063635e422802884d765890e..186a8948cd4e6a53553c4487173da587678480a3 100644 --- a/relational_store/test/js/rdb/unittest/src/RdbstoreEncryptionJsunit.test.js +++ b/relational_store/test/js/rdb/unittest/src/RdbstoreEncryptionJsunit.test.js @@ -16,16 +16,20 @@ import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from ' import data_rdb from '@ohos.data.rdb' import ability_featureAbility from '@ohos.ability.featureAbility' - const TAG = "[RDB_JSKITS_TEST]" -const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " - + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)" +const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)" -var context +let context = null; const STORE_CONFIG_ENCRYPT = { name: "Encrypt.db", encrypt: true, } +const STORE_CONFIG_ENCRYPT2 = { + name: "Encrypt2.db", + encrypt: true, +} const STORE_CONFIG_UNENCRYPT = { name: "Unencrypt.db", encrypt: false, @@ -127,9 +131,9 @@ describe('rdbEncryptTest', function () { /** - * @tc.name RDB Encrypt test + * @tc.name RDB encrypt test * @tc.number SUB_DDM_RDB_JS_RdbEncryptTest_0030 - * @tc.desc RDB Encrypt function test + * @tc.desc RDB encrypt function test */ it('RdbEncryptTest_0030', 0, async function () { await console.log(TAG + "************* RdbEncryptTest_0030 start *************") @@ -159,13 +163,14 @@ describe('rdbEncryptTest', function () { }) /** - * @tc.name RDB Encrypt test + * @tc.name RDB encrypt test * @tc.number SUB_DDM_RDB_JS_RdbEncryptTest_0040 - * @tc.desc RDB Encrypt function test + * @tc.desc RDB encrypt function test */ it('RdbEncryptTest_0040', 0, async function () { await console.log(TAG + "************* RdbEncryptTest_0040 start *************") context = ability_featureAbility.getContext() + await CreateRdbStore(context, STORE_CONFIG_ENCRYPT) try { await CreateRdbStore(context, STORE_CONFIG_WRONG) @@ -176,5 +181,68 @@ describe('rdbEncryptTest', function () { await console.log(TAG + "************* RdbEncryptTest_0040 end *************") }) + + /** + * @tc.name Scenario testcase of RDB, get correct encrypt file when open database + * @tc.number SUB_DDM_RDB_JS_RdbEncryptTest_0050 + * @tc.desc 1. create db1 and insert data + * 2. query db1 + * 3. create db2 and create table in db1 + * 4. query db1 and db2 + */ + it('RdbEncryptTest_0050', 0, async function () { + await console.info(TAG + "************* RdbEncryptTest_0050 start *************") + context = ability_featureAbility.getContext() + let rdbStore1; + let rdbStore2; + // create 'rdbstore1' + try { + rdbStore1 = await CreateRdbStore(context, STORE_CONFIG_ENCRYPT); + } catch (err) { + expect().assertFail() + console.error(`CreatRdbStore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // query 'rdbstore1' + try { + let predicates1 = new data_rdb.RdbPredicates("test") + let resultSet1 = await rdbStore1.query(predicates1) + expect(3).assertEqual(resultSet1.rowCount) + } catch (err) { + expect().assertFail() + console.error(`First query rdbstore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create 'rdbStore2' + try { + rdbStore2 = await CreateRdbStore(context, STORE_CONFIG_ENCRYPT2) + } catch (err) { + expect().assertFail() + console.error(`CreatRdbStore2 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create table and query 'rdbStore1' + try { + await rdbStore1.executeSql(CREATE_TABLE_TEST, null) + let predicates1 = new data_rdb.RdbPredicates("test") + let resultSet1 = await rdbStore1.query(predicates1) + expect(3).assertEqual(resultSet1.rowCount) + } catch (err) { + expect().assertFail() + console.error(`Second query rdbstore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create table and query 'rdbStore2' + try { + await rdbStore2.executeSql(CREATE_TABLE_TEST, null) + let predicates2 = new data_rdb.RdbPredicates("test") + let resultSet2 = await rdbStore2.query(predicates2) + expect(3).assertEqual(resultSet2.rowCount) + } catch (err) { + expect().assertFail() + console.error(`Query rdbstore2 failed, error code: ${err.code}, err message: ${err.message}`); + } + console.info(TAG + "************* RdbEncryptTest_0060 end *************") + }) console.log(TAG + "*************Unit Test End*************") }) \ No newline at end of file diff --git a/relational_store/test/js/rdb/unittest/src/RdbstorePredicatesJsunit.test.js b/relational_store/test/js/rdb/unittest/src/RdbstorePredicatesJsunit.test.js index 0d22de23fb1740e65f869b502e3d487ff839d272..f1abb93fb443c71eb46b130de419ad2ada38f8ae 100644 --- a/relational_store/test/js/rdb/unittest/src/RdbstorePredicatesJsunit.test.js +++ b/relational_store/test/js/rdb/unittest/src/RdbstorePredicatesJsunit.test.js @@ -269,6 +269,36 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testEqualTo0008 end *************"); }) + + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0018 + * @tc.name predicates equalTo test + * @tc.desc 1.equalTo normal test + * 2.equalTo abnormal test + */ + it('testEqualTo0009', 0, async function (done) { + console.log(TAG + "************* testEqualTo0009 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.equalTo('1', 1); + let result1 = await rdbStore.query(predicates1); + expect(true).assertEqual(result1.goToFirstRow()); + expect(3).assertEqual(result1.rowCount) + result1.close() + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.equalTo('1', Number.NaN); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount) + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testEqualTo0009 end *************"); + }) + + /** * @tc.name predicates notEqualTo normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0020 @@ -422,6 +452,33 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testNotEqualTo0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0028 + * @tc.name predicates not equalTo test + * @tc.desc 1.predicates not equalTo normal test + * 2.predicates not equalTo abnormal test + */ + it('testNotEqualTo0009', 0, async function (done) { + console.log(TAG + "************* testNotEqualTo0009 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.notEqualTo('1', 1); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount) + result1.close() + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.notEqualTo('1', Number.NaN); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount) + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testNotEqualTo0009 end *************"); + }) + /** * @tc.name predicates isNull normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0030 @@ -710,6 +767,57 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testGreaterThan0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0058 + * @tc.name predicates greaterThan abnormal test + * @tc.desc 1.predicates greaterThan abnormal "Number.NaN" test + * 2.predicates greaterThan abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates greaterThan abnormal "Number.POSITIVE_INFINITY" test + * 4.predicates greaterThan abnormal "Number.MIN_SAFE_INTEGER" test + * 5.predicates greaterThan abnormal "Number.MAX_SAFE_INTEGER" test + */ + it('testGreaterThan0009', 0, async function (done) { + console.log(TAG + "************* testGreaterThan0009 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.greaterThan("longValue", Number.NaN); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount); + result1.close() + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.greaterThan("longValue", Number.NEGATIVE_INFINITY); + let result2 = await rdbStore.query(predicates2); + expect(3).assertEqual(result2.rowCount); + result2.close() + result2 = null + + let predicates3 = new dataRdb.RdbPredicates("AllDataType"); + predicates3.greaterThan("longValue", Number.POSITIVE_INFINITY); + let result3 = await rdbStore.query(predicates3); + expect(0).assertEqual(result3.rowCount); + result3.close() + result3 = null + + let predicates4 = new dataRdb.RdbPredicates("AllDataType"); + predicates4.greaterThan("longValue", Number.MIN_SAFE_INTEGER); + let result4 = await rdbStore.query(predicates4); + expect(2).assertEqual(result4.rowCount); + result4.close() + result4 = null + + let predicates5 = new dataRdb.RdbPredicates("AllDataType"); + predicates5.greaterThan("longValue", Number.MAX_SAFE_INTEGER); + let result5 = await rdbStore.query(predicates5); + expect(1).assertEqual(result5.rowCount); + result5.close() + result5 = null + + done(); + console.log(TAG + "************* testGreaterThan0009 end *************"); + }) + /** * @tc.name predicates greaterThanOrEqualTo normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0060 @@ -1014,6 +1122,57 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testLessThanOrEqualTo0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0084 + * @tc.name predicates lessThanOrEqualTo abnormal test + * @tc.desc 1.predicates lessThanOrEqualTo abnormal "Number.NaN" test + * 2.predicates lessThanOrEqualTo abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates lessThanOrEqualTo abnormal "Number.POSITIVE_INFINITY" test + * 4.predicates lessThanOrEqualTo abnormal "Number.MAX_VALUE" test + * 5.predicates lessThanOrEqualTo abnormal "Number.MIN_VALUE" test + */ + it('testLessThanOrEqualTo0005', 0, async function (done) { + console.log(TAG + "************* testLessThanOrEqualTo0005 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.lessThanOrEqualTo("longValue", Number.NaN); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount); + result1.close() + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.lessThanOrEqualTo("longValue", Number.NEGATIVE_INFINITY); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount); + result2.close() + result2 = null + + let predicates3 = new dataRdb.RdbPredicates("AllDataType"); + predicates3.lessThanOrEqualTo("longValue", Number.POSITIVE_INFINITY); + let result3 = await rdbStore.query(predicates3); + expect(3).assertEqual(result3.rowCount); + result3.close() + result3 = null + + let predicates4 = new dataRdb.RdbPredicates("AllDataType"); + predicates4.lessThanOrEqualTo("longValue", Number.MAX_VALUE); + let result4 = await rdbStore.query(predicates4); + expect(3).assertEqual(result4.rowCount); + result4.close() + result4 = null + + let predicates5 = new dataRdb.RdbPredicates("AllDataType"); + predicates5.lessThanOrEqualTo("longValue", Number.MIN_VALUE); + let result5 = await rdbStore.query(predicates5); + expect(1).assertEqual(result5.rowCount); + result5.close() + result5 = null + + done(); + console.log(TAG + "************* testLessThanOrEqualTo0005 end *************"); + }) + /** * @tc.name predicates between normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0090 @@ -1166,6 +1325,65 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testBetween0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0098 + * @tc.name predicates between abnormal test + * @tc.desc 1.predicates between abnormal "Number.POSITIVE_INFINITY" test + * 2.predicates between abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates between abnormal "Number.NaN" test + * 4.predicates between abnormal "Number.NaN" test + * 5.predicates between abnormal "Number.MIN_VALUE" test + * 6.predicates between abnormal "Number.MAX_VALUE" test + */ + it('testBetween0009', 0, async function (done) { + console.log(TAG + "************* testBetween0009 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.between("longValue", 0, Number.POSITIVE_INFINITY); + let result1 = await rdbStore.query(predicates1); + expect(2).assertEqual(result1.rowCount); + result1.close(); + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.between("longValue", Number.NEGATIVE_INFINITY, 0); + let result2 = await rdbStore.query(predicates2); + expect(1).assertEqual(result2.rowCount); + result2.close(); + result2 = null + + let predicates3 = new dataRdb.RdbPredicates("AllDataType"); + predicates3.between("longValue", Number.NaN, 0); + let result3 = await rdbStore.query(predicates3); + expect(0).assertEqual(result3.rowCount); + result3.close(); + result3 = null + + let predicates4 = new dataRdb.RdbPredicates("AllDataType"); + predicates4.between("longValue", 0, Number.NaN); + let result4 = await rdbStore.query(predicates4); + expect(0).assertEqual(result4.rowCount); + result4.close(); + result4 = null + + let predicates5 = new dataRdb.RdbPredicates("AllDataType"); + predicates5.between("longValue", Number.MIN_VALUE, 0); + let result5 = await rdbStore.query(predicates5); + expect(0).assertEqual(result5.rowCount); + result5.close(); + result5 = null + + let predicates6 = new dataRdb.RdbPredicates("AllDataType"); + predicates6.between("longValue", 0, Number.MAX_VALUE); + let result6 = await rdbStore.query(predicates6); + expect(2).assertEqual(result6.rowCount); + result6.close(); + result6 = null + + done(); + console.log(TAG + "************* testBetween0009 end *************"); + }) + /** * @tc.name testNotBetween0001 * @tc.number I4JWCV @@ -1242,6 +1460,61 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testNotBetween0004 end *************"); }) + + /** + * @tc.number testNotBetween0005 + * @tc.name test long value with notBetween. + * @tc.desc 1.predicates between abnormal "Number.NaN" test + * 2.predicates between abnormal "Number.NaN" test + * 3.predicates between abnormal "Number.MIN_VALUE" test + * 4.predicates between abnormal "Number.MAX_VALUE" test + * 5.predicates between abnormal "Number.NEGATIVE_INFINITY" test + * 6.predicates between abnormal "Number.POSITIVE_INFINITY" test + */ + it('testNotBetween0005', 0, async function (done) { + console.log(TAG + "************* testNotBetween0005 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.notBetween("longValue", 0, Number.NaN); + let result = await rdbStore.query(predicates1); + expect(1).assertEqual(result.rowCount); + result.close(); + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.notBetween("longValue", Number.NaN, 0); + result = await rdbStore.query(predicates2); + expect(2).assertEqual(result.rowCount); + result.close(); + + let predicates3 = new dataRdb.RdbPredicates("AllDataType"); + predicates3.notBetween("longValue", Number.MIN_VALUE, 0); + result = await rdbStore.query(predicates3); + expect(3).assertEqual(result.rowCount); + result.close(); + + let predicates4 = new dataRdb.RdbPredicates("AllDataType"); + predicates4.notBetween("longValue", 0, Number.MAX_VALUE); + result = await rdbStore.query(predicates4); + expect(1).assertEqual(result.rowCount); + result.close(); + + let predicates5 = new dataRdb.RdbPredicates("AllDataType"); + predicates5.notBetween("longValue", Number.NEGATIVE_INFINITY, 0); + result = await rdbStore.query(predicates5); + expect(2).assertEqual(result.rowCount); + result.close(); + + let predicates6 = new dataRdb.RdbPredicates("AllDataType"); + predicates6.notBetween("longValue", 0, Number.POSITIVE_INFINITY); + result = await rdbStore.query(predicates6); + expect(1).assertEqual(result.rowCount); + result.close(); + result = null + + done(); + console.log(TAG + "************* testNotBetween0005 end *************"); + }) + /** * @tc.name testGlob0001 * @tc.number I4JWCV @@ -1424,6 +1697,34 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testContains0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0104 + * @tc.name predicates contains abnormal test + * @tc.desc 1.predicates contains abnormal "null" test + * 2.predicates contains abnormal "undefined" test + */ + it('testContains0005', 0, async function (done) { + console.log(TAG + "************* testContains0005 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.contains("characterValue", null); + let result1 = await rdbStore.query(predicates1); + expect(3).assertEqual(result1.rowCount); + result1.close() + result1 = null + + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.contains("characterValue", undefined); + let result2 = await rdbStore.query(predicates2); + expect(3).assertEqual(result2.rowCount); + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testContains0005 end *************"); + }) + /** * @tc.name predicates beginsWith normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0110 @@ -1628,6 +1929,34 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testLike0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0133 + * @tc.name predicates like abnormal test + * @tc.desc 1.predicates like abnormal "null" test + * 2.predicates like abnormal "undefined" test + */ + it('testLike0005', 0, async function (done) { + console.log(TAG + "************* testLike0005 start *************"); + + let predicates1 = new dataRdb.RdbPredicates("AllDataType"); + predicates1.like("characterValue", null); + let result1 = await rdbStore.query(predicates1); + expect(3).assertEqual(result1.rowCount); + result1.close() + result1 = null + + let predicates2 = new dataRdb.RdbPredicates("AllDataType"); + predicates2.like("characterValue", undefined); + let result2 = await rdbStore.query(predicates2); + expect(3).assertEqual(result2.rowCount); + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testLike0005 end *************"); + }) + + /** * @tc.name predicates beginWrap normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0140 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js index 864330b091260bc0e7025405e30a0be9e5d74ec2..1dead3602add1177f939e242628d51fd444da114 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js @@ -107,7 +107,7 @@ describe('rdbStoreCloudSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0001 * @tc.desc rdb get modify time using wrong primary key type */ - it('testRdbStoreCloudSync0001', 0, async function () { + it('testRdbStoreCloudSync0001', 0, async function (done) { console.log(TAG + "************* testRdbStoreCloudSync0001 start *************"); try { let key = new Array(); @@ -118,6 +118,7 @@ describe('rdbStoreCloudSyncTest', function () { console.log(TAG + `get modify time, errcode:${JSON.stringify(err)}.`); expect(err.code).assertEqual('401'); } + done(); console.log(TAG + "************* testRdbStoreCloudSync0001 end *************"); }) @@ -131,14 +132,13 @@ describe('rdbStoreCloudSyncTest', function () { try { let PRIKey = ["test_key1", "test_key2"]; rdbStore.getModifyTime("cloud_text", "uuid", PRIKey, function (err, data) { - console.log(TAG + `modifyTime:` + JSON.stringify(err)); + console.log(TAG + `modifyTime:` + JSON.stringify(data)); done(); - expect(err.code).assertEqual(14800000); console.log(TAG + "************* testRdbStoreCloudSync0002 end *************"); }); } catch (err) { console.log(TAG + `get modify time fail, errcode:${JSON.stringify(err)}.`); - done(); + done() expect().assertFail(); } }) @@ -148,15 +148,16 @@ describe('rdbStoreCloudSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0003 * @tc.desc get modify time using string primary key type and promise method */ - it('testRdbStoreCloudSync0003', 0, async function () { + it('testRdbStoreCloudSync0003', 0, async function (done) { console.log(TAG + "************* testRdbStoreCloudSync0003 start *************"); let PRIKey = ["test_key1", "test_key2"]; try { await rdbStore.getModifyTime("cloud_text", "uuid", PRIKey); - expect().assertFail(); + done(); } catch (err) { console.log(TAG + `get modify time fail, errcode:${JSON.stringify(err)}.`); - expect(err.code).assertEqual(14800000); + done(); + expect().assertFail(); } console.log(TAG + "************* testRdbStoreCloudSync0003 end *************"); }) @@ -171,9 +172,8 @@ describe('rdbStoreCloudSyncTest', function () { try { let PRIKey = [1, 3, 4]; rdbStore.getModifyTime("cloud_text", "rowid", PRIKey, function (err, data) { - console.log(TAG + `modifyTime:` + JSON.stringify(err)); + console.log(TAG + `modifyTime:` + JSON.stringify(data)); done(); - expect(err.code).assertEqual(14800000); console.log(TAG + "************* testRdbStoreCloudSync0004 end *************"); }); } catch (err) { @@ -188,22 +188,23 @@ describe('rdbStoreCloudSyncTest', function () { * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0005 * @tc.desc get modify time using rowid and promise method */ - it('testRdbStoreCloudSync0005', 0, async function () { + it('testRdbStoreCloudSync0005', 0, async function (done) { console.log(TAG + "************* testRdbStoreCloudSync0005 start *************"); let PRIKey = [2, 4]; try { await rdbStore.getModifyTime("cloud_text", "roWId", PRIKey); - expect().assertFail(); + done(); } catch (err) { console.log(TAG + `get modify time fail, errcode:${JSON.stringify(err)}.`); - expect(err.code).assertEqual(14800000); + done(); + expect().assertFail(); } console.log(TAG + "************* testRdbStoreCloudSync0005 end *************"); }) /** * @tc.name get modify time, but not set distributed table - * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0004 + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0006 * @tc.desc get modify time, but not set distributed table */ it('testRdbStoreCloudSync0006', 0, async function () { @@ -236,9 +237,8 @@ describe('rdbStoreCloudSyncTest', function () { try { let PRIKey = [1, 2, 4]; rdbStore.getModifyTime("cloud_integer", "uuid", PRIKey, function (err, data) { - console.log(TAG + `modifyTime:` + JSON.stringify(err)); + console.log(TAG + `modifyTime:` + JSON.stringify(data)); done(); - expect(err.code).assertEqual(14800000); console.log(TAG + "************* testRdbStoreCloudSync0007 end *************"); }); } catch (err) { @@ -259,11 +259,10 @@ describe('rdbStoreCloudSyncTest', function () { await rdbStore.getModifyTime("cloud_integer", "uuid", PRIKey).then((err, data) => { console.log(TAG + `modifyTime:` + JSON.stringify(err)); done(); - expect().assertFail(); }).catch((err) => { console.log(TAG + `get modify time fail, errcode:${JSON.stringify(err)}.`); done(); - expect(err.code).assertEqual(14800000); + expect().assertFail(); }); console.log(TAG + "************* testRdbStoreCloudSync0008 end *************"); }) @@ -414,5 +413,54 @@ describe('rdbStoreCloudSyncTest', function () { expect().assertFail(); } }) + + /** + * @tc.name cloud sync with RdbPredicates, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0015 + * @tc.desc cloud sync with RdbPredicates, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + */ + it('testRdbStoreCloudSync0015', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0015 start *************"); + + function Progress(detail) { + console.log(TAG + `Progress:` + JSON.stringify(detail)); + done(); + } + let predicates = await new relationalStore.RdbPredicates("test") + predicates.in("id", ["id1","id2"]); + try { + await rdbStore.cloudSync(relationalStore.SyncMode.SYNC_MODE_CLOUD_FIRST, predicates, Progress) + } catch (err) { + console.log(TAG + `cloud sync fail, errcode:${JSON.stringify(err)}.`); + expect("202").assertEqual(err.code) + } + done(); + console.log(TAG + "************* testRdbStoreCloudSync0015 end *************"); + }) + + /** + * @tc.name cloud sync with RdbPredicates, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0015 + * @tc.desc cloud sync with RdbPredicates, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + */ + it('testRdbStoreCloudSync0016', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0016 start *************"); + try { + + function Progress(detail) { + console.log(TAG + `Progress:` + JSON.stringify(detail)); + } + let predicates = await new relationalStore.RdbPredicates("test") + predicates.in("id", ["id1","id2"]); + rdbStore.cloudSync(relationalStore.SyncMode.SYNC_MODE_TIME_FIRST, predicates, Progress, () => { + expect(false).assertTrue() + }); + } catch (err) { + console.log(TAG + `cloud sync fail, errcode:${JSON.stringify(err)}.`); + expect("202").assertEqual(err.code) + } + done(); + console.log(TAG + "************* testRdbStoreCloudSync0016 end *************"); + }) console.log(TAG + "*************Unit Test End*************"); }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js index a56f352531e41cd23f1ef49d61d60e8529052322..1dd2d2b86fd14897066f73f99c600ac13a246f91 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js @@ -444,5 +444,94 @@ describe('rdbStoreDistributedTest', function () { console.log(TAG + "************* testRdbStoreDistributed0020 end *************"); done() }) + + /** + * @tc.name subscribe test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Distributed_021 + * @tc.desc normal testcase for autoSyncProgress of interface 'on' + */ + it('testRdbStoreDistributed0021', 0, async function () { + console.log(TAG + "************* testRdbStoreDistributed0021 start *************"); + try { + rdbStore.on("autoSyncProgress", function (detail) { + console.log(TAG + `Progress:` + JSON.stringify(detail)); + }); + console.log(TAG + "on autoSyncProgress success"); + } catch (err) { + console.log(TAG + "on autoSyncProgress" + err); + expect().assertFail(); + } + console.log(TAG + "************* testRdbStoreDistributed0021 end *************"); + }) + + /** + * @tc.name subscribe test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Distributed_022 + * @tc.desc normal testcase for autoSyncProgress of interface 'off' + */ + it('testRdbStoreDistributed0022', 0, async function () { + console.log(TAG + "************* testRdbStoreDistributed0022 start *************"); + try { + rdbStore.off("autoSyncProgress", function (detail) { + console.log(TAG + `Progress:` + JSON.stringify(detail)); + }); + console.log(TAG + "off autoSyncProgress success"); + } catch (err) { + console.log(TAG + "off autoSyncProgress" + err); + expect().assertFail(); + } + console.log(TAG + "************* testRdbStoreDistributed0022 end *************"); + }) + + /** + * @tc.name subscribe test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Distributed_023 + * @tc.desc normal testcase for autoSyncProgress of interface 'off' + */ + it('testRdbStoreDistributed0023', 0, async function () { + console.log(TAG + "************* testRdbStoreDistributed0023 start *************"); + try { + rdbStore.off("autoSyncProgress", null); + console.log(TAG + "off autoSyncProgress success"); + } catch (err) { + console.log(TAG + "off autoSyncProgress" + err); + expect().assertFail(); + } + console.log(TAG + "************* testRdbStoreDistributed0023 end *************"); + }) + + /** + * @tc.name subscribe test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Distributed_024 + * @tc.desc normal testcase for autoSyncProgress of interface 'off' + */ + it('testRdbStoreDistributed0024', 0, async function () { + console.log(TAG + "************* testRdbStoreDistributed0024 start *************"); + try { + rdbStore.off("autoSyncProgress", undefined); + console.log(TAG + "off autoSyncProgress success"); + } catch (err) { + console.log(TAG + "off autoSyncProgress" + err); + expect().assertFail(); + } + console.log(TAG + "************* testRdbStoreDistributed0024 end *************"); + }) + + /** + * @tc.name subscribe test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Distributed_025 + * @tc.desc normal testcase for autoSyncProgress of interface 'off' + */ + it('testRdbStoreDistributed0025', 0, async function () { + console.log(TAG + "************* testRdbStoreDistributed0025 start *************"); + try { + rdbStore.off("autoSyncProgress"); + console.log(TAG + "off autoSyncProgress success"); + } catch (err) { + console.log(TAG + "off autoSyncProgress" + err); + expect().assertFail(); + } + console.log(TAG + "************* testRdbStoreDistributed0025 end *************"); + }) console.log(TAG + "*************Unit Test End*************"); }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js new file mode 100644 index 0000000000000000000000000000000000000000..6a55f00dd75535a2b6506b123a7ae91b55c6d313 --- /dev/null +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js @@ -0,0 +1,436 @@ +/* + * 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. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import data_relationalStore from '@ohos.data.relationalStore'; +import ability_featureAbility from '@ohos.ability.featureAbility'; + +const TAG = "[RELATIONAL_STORE_CUSTOMDIR_TEST]" + +const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB, data1 asset, data2 assets)"; + +const STORE_CONFIG1 = { + name: "RdbCustomDir1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "custom1/subCustom1", +}; + +const STORE_CONFIG2 = { + name: "RdbCustomDir2.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "custom2/subCustom2", +}; + +const STORE_CONFIG3 = { + name: "RdbCustomDir3.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "custom", +}; + +const STORE_CONFIG4 = { + name: "RdbCustomDir4.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "custom".repeat(1000), +}; + +const asset1 = { + name: "name1", + uri: "uri1", + createTime: "createTime1", + modifyTime: "modifyTime1", + size: "size1", + path: "path1", + status: data_relationalStore.AssetStatus.ASSET_NORMAL, +} + +const asset2 = { + name: "name2", + uri: "uri2", + createTime: "createTime2", + modifyTime: "modifyTime2", + size: "size2", + path: "path2", + status: data_relationalStore.AssetStatus.ASSET_NORMAL, +} + +let context = ability_featureAbility.getContext(); + +let store = null; + +describe('rdbStoreCustomTest', function () { + beforeAll(function () { + console.info(TAG, 'beforeAll') + }) + + beforeEach(async function () { + console.info(TAG, 'beforeEach') + }) + + afterEach(async function () { + console.info(TAG, 'afterEach') + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG1); + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG2); + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG3); + store = null; + }) + + afterAll(async function () { + console.info(TAG, 'afterAll') + }) + + async function InsertTest() { + console.info(TAG, "insertTest data start"); + let u8 = new Uint8Array([1, 2, 3]); + const assets1 = [asset1, asset2]; + let valuesBucket1 = { + "id": 1, + "name": "lisi", + "age": 15, + "salary": 153.3, + "blobType": u8, + "data1": asset1, + "data2": assets1, + } + await store.insert("test", valuesBucket1); + let valuesBucket2 = { + "id": 2, + "name": "tom", + "age": 16, + "salary": 1503.3, + } + await store.insert("test", valuesBucket2); + console.info(TAG, "insertTest data end"); + } + + async function UpdateTest() { + console.info(TAG, "updateTest data start"); + let u8 = new Uint8Array([1, 2, 3]); + const assets1 = [asset2]; + let valuesBucket = { + "id": 1, + "name": "tim", + "age": 18, + "salary": 1563.3, + "blobType": u8, + "data1": asset2, + "data2": assets1, + } + let predicates = new data_relationalStore.RdbPredicates("test") + predicates.equalTo("id", "1") + await store.update(valuesBucket, predicates); + console.info(TAG, "updateTest data end"); + } + + console.info(TAG, "*************Unit Test Begin*************"); + + /** + * @tc.number testRdbStoreCustomDirTest0001 + * @tc.name Normal test case of getRdbStore, test single-layer directory + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest0001', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0001 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG3); + expect(store != null).assertTrue(); + done(); + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0001 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0002 + * @tc.name Normal test case of deleteRdbStore, Configure customDir + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + * 3.Execute deleteRdbStore by StoreConfig + */ + it('testRdbStoreCustomDirTest0002', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0002 start *************"); + try { + let store1 = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + expect(store1 != null).assertTrue(); + store1 = null; + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG1); + done(); + } catch(err) { + console.error(TAG, "catch err: Delete RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0002 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0003 + * @tc.name Normal test case of getRdbStore, test multi-layer directory and create two stores + * @tc.desc 1.Configure database name and securityLevel and customDir + * 2.Execute getRdbStore1 + * 3.Execute getRdbStore2 + * 4.Execute deleteRdbStore1 + * 5.Execute deleteRdbStore2 + */ + it('testRdbStoreCustomDirTest0003', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0003 start *************"); + try { + let store1 = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + expect(store1 != null).assertTrue(); + store1 = null; + } catch(err) { + console.error(TAG, "catch err: Get RdbStore1 failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + let store2 = await data_relationalStore.getRdbStore(context, STORE_CONFIG2); + expect(store2 != null).assertTrue(); + store2 = null; + done(); + } catch(err) { + console.error(TAG, "catch err: Get RdbStore2 failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0003 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0004 + * @tc.name Normal test case of getRdbStore, test insert and query data + * @tc.desc 1.Configure database name and securityLevel and customDir + * 2.Execute getRdbStore + * 3.Execute insert data + * 4.Execute query data + */ + it('testRdbStoreCustomDirTest0004', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0004 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + expect(store != null).assertTrue(); + await store.executeSql(CREATE_TABLE_TEST,) + } catch(err) { + console.error(TAG, "catch err: Get RdbStore2 failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + await InsertTest(); + } catch(err) { + console.error(TAG, "catch err: Insert data failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + let predicates = new data_relationalStore.RdbPredicates("test"); + let resultSet = await store.query(predicates); + expect(2).assertEqual(resultSet.rowCount); + done(); + } catch(err) { + console.error(TAG, "catch err: query data failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0004 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0005 + * @tc.name Normal test case of getRdbStore, test update and query data + * @tc.desc 1.Configure database name and securityLevel and customDir + * 2.Execute getRdbStore + * 3.Execute insert data + * 4.Execute update data + * 5.Execute query data + */ + it('testRdbStoreCustomDirTest0005', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0005 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + expect(store != null).assertTrue(); + await store.executeSql(CREATE_TABLE_TEST,) + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + await InsertTest(); + await UpdateTest(); + } catch(err) { + console.error(TAG, "catch err: Insert and update data failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + let predicates = new data_relationalStore.RdbPredicates("test"); + let resultSet = await store.query(predicates); + expect(2).assertEqual(resultSet.rowCount); + expect(true).assertEqual(resultSet.goToFirstRow()); + expect("tim").assertEqual(resultSet.getString(resultSet.getColumnIndex("name"))); + done(); + } catch(err) { + console.error(TAG, "catch err: query data failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0005 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0006 + * @tc.name Normal test case of getRdbStore, if customDir is "" + * @tc.desc 1.Configure customDir as "" + * 2.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest0006', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0006 start *************"); + try { + const STORE_CONFIG = { + name: "RdbCustom1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "", + }; + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG); + expect(store != null).assertTrue(); + done(); + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + console.info(TAG, "************* testRdbStoreCustomDirTest0006 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0007 + * @tc.name Normal test case of deleteRdbStore, if customDir is null + * @tc.desc 1.Configure customDir as null + * 2.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest0007', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0007 start *************"); + try { + const STORE_CONFIG = { + name: "RdbCustom1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: null, + }; + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG); + expect(store != null).assertTrue(); + done(); + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0007 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0008 + * @tc.name Normal test case of deleteRdbStore, if customDir is undefined + * @tc.desc 1.Configure customDir as undefined + * 2.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest0008', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0008 start *************"); + try { + const STORE_CONFIG = { + name: "RdbCustom1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: undefined, + }; + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG); + expect(store != null).assertTrue(); + done(); + } catch(err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0008 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0009 + * @tc.name Normal test case of getRdbStore, test get store after getting store + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + * 3.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest0009', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0009 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG3); + expect(store != null).assertTrue(); + } catch (err) { + console.error(TAG, "catch err: Get RdbStore1 failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG3); + expect(store != null).assertTrue(); + done(); + } catch (err) { + console.error(TAG, "catch err: Get RdbStore2 failed, err: code=" + err.code + " message=" + err.message); + expect(false).assertTrue(); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0009 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest00010 + * @tc.name AbNormal test case of getRdbStore, if customDir length exceeds 1024 bytes + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + */ + it('testRdbStoreCustomDirTest00010', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest00010 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG4); + expect(false).assertTrue(); + } catch (err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect("401").assertEqual(err.code); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest00010 end *************") + }) + + console.info(TAG, "*************Unit Test End*************"); +}) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreDeleteJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreDeleteJsunit.test.js index c61deed0e12d74ecaa5b763fd29c2100afa7689a..b2456716e62e06daeba39cfc7a903ecf769c4603 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreDeleteJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreDeleteJsunit.test.js @@ -51,9 +51,10 @@ describe('rdbStoreDeleteTest', function () { console.log(TAG + "*************Unit Test Begin*************"); /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0010 - * @tc.desc rdb delete test + * @tc.name Normal test case of delete + * @tc.desc 1.Insert data + * 2.Execute delete */ it('testRdbStoreDelete0001', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0001 start *************"); @@ -101,9 +102,11 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0020 - * @tc.desc rdb delete test + * @tc.name Normal test case of delete, "name" is "zhangsan" + * @tc.desc 1.Insert data + * 2.Configure predicates ("name": "zhangsan") + * 3.Execute delete */ it('testRdbStoreDelete0002', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0002 start *************"); @@ -152,9 +155,12 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0030 - * @tc.desc rdb delete test + * @tc.name Normal test case of query and delete, "age" is 28 + * @tc.desc 1.Insert data + * 2.Query data ("age", 28) + * 3.Execute delete ("age", 28) + * 4.Query data ("age", 28) */ it('testRdbStoreDelete0003', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0003 start *************"); @@ -208,9 +214,11 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0040 - * @tc.desc rdb delete test + * @tc.name Abnormal test case of delete, if column is invalid + * @tc.desc 1.Insert data + * 2.Configure predicates ("aaa id", 1) + * 3.Execute delete */ it('testRdbStoreDelete0004', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0004 start *************"); @@ -258,9 +266,11 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0050 - * @tc.desc rdb delete test + * @tc.name Normal test case of delete, "name" is "lisi" + * @tc.desc 1.Insert data + * 2.Configure predicates ("name", "lisi") + * 3.Execute delete */ it('testRdbStoreDelete0005', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0005 start *************"); @@ -309,9 +319,10 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0060 - * @tc.desc rdb delete test + * @tc.name Abnormal test case of delete, if TABLE "name" is "" + * @tc.desc 1.Configure predicates ("name", "") + * 2.Execute delete */ it('testRdbStoreDelete0006', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0006 start *************"); @@ -335,9 +346,10 @@ describe('rdbStoreDeleteTest', function () { }) /** - * @tc.name rdb delete test - * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0060 - * @tc.desc rdb delete test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Delete_0070 + * @tc.name Abnormal test case of delete, if non system application calls + * @tc.desc 1.Configure predicates (Calling system application) + * 2.Execute delete */ it('testRdbStoreDelete0007', 0, async function (done) { console.log(TAG + "************* testRdbStoreDelete0007 start *************"); @@ -354,4 +366,4 @@ describe('rdbStoreDeleteTest', function () { }) console.log(TAG + "*************Unit Test End*************"); -}) \ No newline at end of file +}) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js index 83f0ef6b41f4df4b6290387e2fc06bb9f17dcbf6..a6a477ec9b02fb14669c7cbc7e4c4b4f0e9ed1d4 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js @@ -16,17 +16,21 @@ import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from ' import data_relationalStore from '@ohos.data.relationalStore' import ability_featureAbility from '@ohos.ability.featureAbility' - const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)" -var context = ability_featureAbility.getContext() +let context = ability_featureAbility.getContext() const STORE_CONFIG_ENCRYPT = { name: "Encrypt.db", encrypt: true, securityLevel: data_relationalStore.SecurityLevel.S1, } +const STORE_CONFIG_ENCRYPT2 = { + name: "Encrypt2.db", + encrypt: true, + securityLevel: data_relationalStore.SecurityLevel.S1, +} const STORE_CONFIG_UNENCRYPT = { name: "Unencrypt.db", encrypt: false, @@ -222,5 +226,68 @@ describe('rdbEncryptTest', function () { } console.log(TAG + "************* RdbEncryptTest_0050 end *************") }) + + /** + * @tc.name Scenario testcase of RDB, get correct encrypt file when open database + * @tc.number SUB_DDM_RDB_JS_RdbEncryptTest_0060 + * @tc.desc 1. create db1 and insert data + * 2. query db1 + * 3. create db2 and create table in db1 + * 4. query db1 and db2 + */ + it('RdbEncryptTest_0060', 0, async function () { + await console.info(TAG + "************* RdbEncryptTest_0060 start *************") + context = ability_featureAbility.getContext() + let rdbStore1; + let rdbStore2; + // create 'rdbstore1' + try { + rdbStore1 = await CreatRdbStore(context, STORE_CONFIG_ENCRYPT); + } catch (err) { + expect().assertFail() + console.error(`CreatRdbStore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // query 'rdbstore1' + try { + let predicates1 = new data_relationalStore.RdbPredicates("test") + let resultSet1 = await rdbStore1.query(predicates1) + expect(3).assertEqual(resultSet1.rowCount) + } catch (err) { + expect().assertFail() + console.error(`First query rdbstore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create 'rdbStore2' + try { + rdbStore2 = await CreatRdbStore(context, STORE_CONFIG_ENCRYPT2) + } catch (err) { + expect().assertFail() + console.error(`CreatRdbStore2 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create table and query 'rdbStore1' + try { + await rdbStore1.executeSql(CREATE_TABLE_TEST, null) + let predicates1 = new data_relationalStore.RdbPredicates("test") + let resultSet1 = await rdbStore1.query(predicates1) + expect(3).assertEqual(resultSet1.rowCount) + } catch (err) { + expect().assertFail() + console.error(`Second query rdbstore1 failed, error code: ${err.code}, err message: ${err.message}`); + } + + // create table and query 'rdbStore2' + try { + await rdbStore2.executeSql(CREATE_TABLE_TEST, null) + let predicates2 = new data_relationalStore.RdbPredicates("test") + let resultSet2 = await rdbStore2.query(predicates2) + expect(3).assertEqual(resultSet2.rowCount) + } catch (err) { + expect().assertFail() + console.error(`Query rdbstore2 failed, error code: ${err.code}, err message: ${err.message}`); + } + console.info(TAG + "************* RdbEncryptTest_0060 end *************") + }) console.log(TAG + "*************Unit Test End*************") }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js index 31a536d3cc5560a1e74737fcab6fdc2685508318..dd9b4030ca9a22c168069e5c1e2276f0b9b9681a 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js @@ -54,9 +54,10 @@ describe('rdbStoreInsertTest', function () { console.log(TAG + "*************Unit Test Begin*************"); /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0001 - * @tc.desc rdb insert test + * @tc.name Normal test case of insert + * @tc.desc 1.Insert data + * 2.Query data */ it('testRdbStoreInsert0001', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0001 start *************"); @@ -119,9 +120,10 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0002 - * @tc.desc rdb insert test + * @tc.name Abnormal test case of insert, if TABLE name is wrong + * @tc.desc 1.Create value + * 2.Execute insert (with wrong table) */ it('testRdbStoreInsert0002', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0002 start *************"); @@ -147,9 +149,10 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0003 - * @tc.desc rdb insert test + * @tc.name Abnormal test case of insert, if TABLE name is null + * @tc.desc 1.Create value + * 2.Execute insert (with null table) */ it('testRdbStoreInsert0003', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0003 start *************"); @@ -182,9 +185,11 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0004 - * @tc.desc rdb insert Extra long character test + * @tc.name Normal test case of insert (long string and special characters) + * @tc.desc 1.Insert data + * 2.Configure predicates + * 3.Query data */ it('testRdbStoreInsert0004', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0004 start *************"); @@ -216,9 +221,11 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0005 - * @tc.desc rdb insert Extra long character test + * @tc.name Normal test case of insert (Chinese and long string) + * @tc.desc 1.Insert data + * 2.Configure predicates + * 3.Query data */ it('testRdbStoreInsert0005', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0005 start *************"); @@ -250,9 +257,11 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0006 - * @tc.desc rdb insert Extra long character test + * @tc.name Normal test case of insert (Chinese and long string) + * @tc.desc 1.Insert data + * 2.Configure predicates + * 3.Query data */ it('testRdbStoreInsert0006', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0006 start *************"); @@ -284,9 +293,11 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0007 - * @tc.desc rdb insert test + * @tc.name Normal test case of insert boundary value + * @tc.desc 1.Insert data + * 2.Configure predicates + * 3.Query data */ it('testRdbStoreInsert0007', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0007 start *************"); @@ -337,9 +348,13 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0008 - * @tc.desc rdb insert test + * @tc.name Normal test case of insert null value + * @tc.desc 1.Insert data + * 2.Query data + * 3.Create value + * 4.Execute update + * 5.Query data */ it('testRdbStoreInsert0008', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0008 start *************"); @@ -403,9 +418,10 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb insert test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0009 - * @tc.desc rdb insert test + * @tc.name Abnormal test case of insert, if value invalid + * @tc.desc 1.Create value ("age": new Date()) + * 2.Execute insert */ it('testRdbStoreInsert0009', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0009 start *************"); @@ -437,9 +453,10 @@ describe('rdbStoreInsertTest', function () { /** - * @tc.name rdb inserttWithConflictResolution test * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0001 - * @tc.desc rdb insertWithConflictResolution test + * @tc.name Abnormal test case of insert, if primary key conflict + * @tc.desc 1.Insert data + * 2.Insert data (conflict "id") */ it('InsertWithConflictResolution0001', 0, async function (done) { console.log(TAG + "************* InsertWithConflictResolution0001 start *************"); @@ -484,9 +501,14 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb inserttWithConflictResolution test * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0002 - * @tc.desc rdb insertWithConflictResolution test + * @tc.name Abnormal test case of insert with ON_CONFLICT_ROLLBACK, if primary key conflict + * @tc.desc 1.Insert data with ON_CONFLICT_ROLLBACK + * 2.Create value (conflict "id") + * 3.Begin Transaction + * 4.Insert data + * 5.Insert data with ON_CONFLICT_ROLLBACK (conflict "id") + * 6.Query data */ it('InsertWithConflictResolution0002', 0, async function (done) { console.log(TAG + "************* InsertWithConflictResolution0002 start *************"); @@ -542,9 +564,12 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb inserttWithConflictResolution test * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0003 - * @tc.desc rdb insertWithConflictResolution test + * @tc.name Normal test case of insert with ON_CONFLICT_IGNORE, if primary key conflict + * @tc.desc 1.Insert data with ON_CONFLICT_IGNORE + * 2.Insert data with ON_CONFLICT_IGNORE (conflict "id") + * 3.Configure predicates ("name" is "zhangsan") + * 4.Query data */ it('InsertWithConflictResolution0003', 0, async function (done) { console.log(TAG + "************* InsertWithConflictResolution0003 start *************"); @@ -590,9 +615,12 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb inserttWithConflictResolution test * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0004 - * @tc.desc rdb insertWithConflictResolution test + * @tc.name Normal test case of insert with ON_CONFLICT_REPLACE, if primary key conflict + * @tc.desc 1.Insert data with ON_CONFLICT_REPLACE + * 2.Query data ("name" is "zhangsan") + * 3.Insert data with ON_CONFLICT_REPLACE (conflict "id") + * 4.Query data */ it('InsertWithConflictResolution0004', 0, async function (done) { console.log(TAG + "************* InsertWithConflictResolution0004 start *************"); @@ -661,9 +689,10 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name rdb inserttWithConflictResolution test * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0005 - * @tc.desc rdb insertWithConflictResolution test + * @tc.name Abnormal test case of insert, if param conflict is invalid + * @tc.desc 1.Create value + * 2.Execute insert (param conflict is 6) */ it('InsertWithConflictResolution0005', 0, async function (done) { console.log(TAG + "************* InsertWithConflictResolution0005 start *************"); @@ -690,10 +719,12 @@ describe('rdbStoreInsertTest', function () { }) /** - * @tc.name: rdb batchInsert test - * @tc.number: SUB_DDM_AppDataFWK_JSRDB_batchInsert_0001 - * @tc.desc: rdb batchInsert test - * @tc.require: issueI5GZGX + * @tc.number SUB_DDM_AppDataFWK_JSRDB_batchInsert_0001 + * @tc.name Normal test case of batchInsert + * @tc.desc 1.Create valueBucket + * 2.Execute push + * 3.BatchInsert data + * 4.Query data */ it('testRdbStorebatchInsert001', 0, async function () { console.log(TAG + "************* testRdbStorebatchInsert001 start *************"); diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js index bda40f9e22f9f335637c9daec40a00c4e1134a2d..b2a494292b6668ba24f133ec8e51cfb293318a9c 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js @@ -273,6 +273,34 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testEqualTo0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0018 + * @tc.name predicates equalTo test + * @tc.desc 1.equalTo normal test + * 2.equalTo abnormal test + */ + it('testEqualTo0009', 0, async function (done) { + console.log(TAG + "************* testEqualTo0009 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.equalTo('1', 1); + let result1 = await rdbStore.query(predicates1); + expect(true).assertEqual(result1.goToFirstRow()); + expect(3).assertEqual(result1.rowCount) + result1.close() + result1 = null + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.equalTo('1', Number.NaN); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount) + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testEqualTo0009 end *************"); + }) + /** * @tc.name predicates notEqualTo normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0020 @@ -426,6 +454,34 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testNotEqualTo0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0028 + * @tc.name predicates not equalTo test + * @tc.desc 1.predicates not equalTo normal test + * 2.predicates not equalTo abnormal test + */ + it('testNotEqualTo0009', 0, async function (done) { + console.log(TAG + "************* testNotEqualTo0009 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.notEqualTo('1', 1); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount) + result1.close() + result1 = null + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.notEqualTo('1', Number.NaN); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount) + result2.close() + result2 = null + + done(); + console.log(TAG + "************* testNotEqualTo0009 end *************"); + }) + + /** * @tc.name predicates isNull normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0030 @@ -714,6 +770,58 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testGreaterThan0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0058 + * @tc.name predicates greaterThan abnormal test + * @tc.desc 1.predicates greaterThan abnormal "Number.NaN" test + * 2.predicates greaterThan abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates greaterThan abnormal "Number.POSITIVE_INFINITY" test + * 4.predicates greaterThan abnormal "Number.MIN_SAFE_INTEGER" test + * 5.predicates greaterThan abnormal "Number.MAX_SAFE_INTEGER" test + */ + it('testGreaterThan0009', 0, async function (done) { + console.log(TAG + "************* testGreaterThan0009 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.greaterThan("longValue", Number.NaN); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount); + result1.close() + result1 = null + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.greaterThan("longValue", Number.NEGATIVE_INFINITY); + let result2 = await rdbStore.query(predicates2); + expect(3).assertEqual(result2.rowCount); + result2.close() + result2 = null + + let predicates3 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates3.greaterThan("longValue", Number.POSITIVE_INFINITY); + let result3 = await rdbStore.query(predicates3); + expect(0).assertEqual(result3.rowCount); + result3.close() + result3 = null + + let predicates4 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates4.greaterThan("longValue", Number.MIN_SAFE_INTEGER); + let result4 = await rdbStore.query(predicates4); + expect(2).assertEqual(result4.rowCount); + result4.close() + result4 = null + + let predicates5 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates5.greaterThan("longValue", Number.MAX_SAFE_INTEGER); + let result5 = await rdbStore.query(predicates5); + expect(1).assertEqual(result5.rowCount); + result5.close() + result5 = null + + done(); + console.log(TAG + "************* testGreaterThan0009 end *************"); + }) + + /** * @tc.name predicates greaterThanOrEqualTo normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0060 @@ -1018,6 +1126,57 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testLessThanOrEqualTo0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0084 + * @tc.name predicates lessThanOrEqualTo abnormal test + * @tc.desc 1.predicates lessThanOrEqualTo abnormal "Number.NaN" test + * 2.predicates lessThanOrEqualTo abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates lessThanOrEqualTo abnormal "Number.POSITIVE_INFINITY" test + * 4.predicates lessThanOrEqualTo abnormal "Number.MAX_VALUE" test + * 5.predicates lessThanOrEqualTo abnormal "Number.MIN_VALUE" test + */ + it('testLessThanOrEqualTo0005', 0, async function (done) { + console.log(TAG + "************* testLessThanOrEqualTo0005 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.lessThanOrEqualTo("longValue", Number.NaN); + let result1 = await rdbStore.query(predicates1); + expect(0).assertEqual(result1.rowCount); + result1.close() + result1 = null + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.lessThanOrEqualTo("longValue", Number.NEGATIVE_INFINITY); + let result2 = await rdbStore.query(predicates2); + expect(0).assertEqual(result2.rowCount); + result2.close() + result2 = null + + let predicates3 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates3.lessThanOrEqualTo("longValue", Number.POSITIVE_INFINITY); + let result3 = await rdbStore.query(predicates3); + expect(3).assertEqual(result3.rowCount); + result3.close() + result3 = null + + let predicates4 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates4.lessThanOrEqualTo("longValue", Number.MAX_VALUE); + let result4 = await rdbStore.query(predicates4); + expect(3).assertEqual(result4.rowCount); + result4.close() + result4 = null + + let predicates5 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates5.lessThanOrEqualTo("longValue", Number.MIN_VALUE); + let result5 = await rdbStore.query(predicates5); + expect(1).assertEqual(result5.rowCount); + result5.close() + result5 = null + + done(); + console.log(TAG + "************* testLessThanOrEqualTo0005 end *************"); + }) + /** * @tc.name predicates between normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0090 @@ -1170,6 +1329,65 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testBetween0008 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0098 + * @tc.name predicates between abnormal test + * @tc.desc 1.predicates between abnormal "Number.POSITIVE_INFINITY" test + * 2.predicates between abnormal "Number.NEGATIVE_INFINITY" test + * 3.predicates between abnormal "Number.NaN" test + * 4.predicates between abnormal "Number.NaN" test + * 5.predicates between abnormal "Number.MIN_VALUE" test + * 6.predicates between abnormal "Number.MAX_VALUE" test + */ + it('testBetween0009', 0, async function (done) { + console.log(TAG + "************* testBetween0009 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.between("longValue", 0, Number.POSITIVE_INFINITY); + let result1 = await rdbStore.query(predicates1); + expect(2).assertEqual(result1.rowCount); + result1.close(); + result1 = null + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.between("longValue", Number.NEGATIVE_INFINITY, 0); + let result2 = await rdbStore.query(predicates2); + expect(1).assertEqual(result2.rowCount); + result2.close(); + result2 = null + + let predicates3 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates3.between("longValue", Number.NaN, 0); + let result3 = await rdbStore.query(predicates3); + expect(0).assertEqual(result3.rowCount); + result3.close(); + result3 = null + + let predicates4 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates4.between("longValue", 0, Number.NaN); + let result4 = await rdbStore.query(predicates4); + expect(0).assertEqual(result4.rowCount); + result4.close(); + result4 = null + + let predicates5 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates5.between("longValue", Number.MIN_VALUE, 0); + let result5 = await rdbStore.query(predicates5); + expect(0).assertEqual(result5.rowCount); + result5.close(); + result5 = null + + let predicates6 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates6.between("longValue", 0, Number.MAX_VALUE); + let result6 = await rdbStore.query(predicates6); + expect(2).assertEqual(result6.rowCount); + result6.close(); + result6 = null + + done(); + console.log(TAG + "************* testBetween0009 end *************"); + }) + /** * @tc.name testNotBetween0001 * @tc.number I4JWCV @@ -1246,6 +1464,60 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testNotBetween0004 end *************"); }) + /** + * @tc.number testNotBetween0005 + * @tc.name test long value with notBetween. + * @tc.desc 1.predicates between abnormal "Number.NaN" test + * 2.predicates between abnormal "Number.NaN" test + * 3.predicates between abnormal "Number.MIN_VALUE" test + * 4.predicates between abnormal "Number.MAX_VALUE" test + * 5.predicates between abnormal "Number.NEGATIVE_INFINITY" test + * 6.predicates between abnormal "Number.POSITIVE_INFINITY" test + */ + it('testNotBetween0005', 0, async function (done) { + console.log(TAG + "************* testNotBetween0005 start *************"); + + let predicates1 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates1.notBetween("longValue", 0, Number.NaN); + let result = await rdbStore.query(predicates1); + expect(1).assertEqual(result.rowCount); + result.close(); + + let predicates2 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates2.notBetween("longValue", Number.NaN, 0); + result = await rdbStore.query(predicates2); + expect(2).assertEqual(result.rowCount); + result.close(); + + let predicates3 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates3.notBetween("longValue", Number.MIN_VALUE, 0); + result = await rdbStore.query(predicates3); + expect(3).assertEqual(result.rowCount); + result.close(); + + let predicates4 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates4.notBetween("longValue", 0, Number.MAX_VALUE); + result = await rdbStore.query(predicates4); + expect(1).assertEqual(result.rowCount); + result.close(); + + let predicates5 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates5.notBetween("longValue", Number.NEGATIVE_INFINITY, 0); + result = await rdbStore.query(predicates5); + expect(2).assertEqual(result.rowCount); + result.close(); + + let predicates6 = new data_relationalStore.RdbPredicates("AllDataType"); + predicates6.notBetween("longValue", 0, Number.POSITIVE_INFINITY); + result = await rdbStore.query(predicates6); + expect(1).assertEqual(result.rowCount); + result.close(); + result = null + + done(); + console.log(TAG + "************* testNotBetween0005 end *************"); + }) + /** * @tc.name testGlob0001 * @tc.number I4JWCV @@ -1428,6 +1700,37 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testContains0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0104 + * @tc.name predicates contains abnormal test + * @tc.desc 1.predicates contains abnormal "null" test + * 2.predicates contains abnormal "undefined" test + */ + it('testContains0005', 0, async function (done) { + console.info(TAG, `************* testContains0005 start *************`); + try { + let predicates = new data_relationalStore.RdbPredicates("AllDataType"); + predicates.contains("characterValue", null); + expect(null).assertFail(); + done(); + } catch (err) { + console.error(TAG, `predicates.contains failed: err code=${err.code}, message=${err.message}`); + expect("401").assertEqual(err.code); + } + + try { + let predicates = new data_relationalStore.RdbPredicates("AllDataType"); + predicates.contains("characterValue", undefined); + expect(null).assertFail(); + done(); + } catch (err) { + console.error(TAG, `predicates.contains failed: err code=${err.code}, message=${err.message}`); + expect("401").assertEqual(err.code); + done(); + } + console.info(TAG, `************* testContains0005 end *************`); + }) + /** * @tc.name predicates beginsWith normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0110 @@ -1632,6 +1935,37 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testLike0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0134 + * @tc.name predicates like abnormal test + * @tc.desc 1.predicates like abnormal "null" test + * 2.predicates like abnormal "undefined" test + */ + it('testLike0005', 0, async function (done) { + console.info(TAG, `************* testLike0005 start *************`); + try { + let predicates = new data_relationalStore.RdbPredicates("AllDataType"); + predicates.like("characterValue", null); + expect(null).assertFail(); + done(); + } catch (err) { + console.error(TAG, `predicates.like failed: err code=${err.code}, message=${err.message}`); + expect("401").assertEqual(err.code); + } + + try { + let predicates = new data_relationalStore.RdbPredicates("AllDataType"); + predicates.like("characterValue", undefined); + expect(null).assertEqual(); + done(); + } catch (err) { + console.error(TAG, `predicates.like failed: err code=${err.code}, message=${err.message}`); + expect("401").assertEqual(err.code); + done(); + } + console.info(TAG, `************* testLike0005 end *************`); + }) + /** * @tc.name predicates beginWrap normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0140 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js index 9998916f86c5cde7082946fc419ce884ca7a2675..413dc1fa606d1a4cb460f6fcdeecd1ce75180b61 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js @@ -215,7 +215,7 @@ describe('rdbStorePromiseTest', function () { /** * @tc.number testRdbStorePromiseTest0006 * @tc.name Abnormal test case of getRdbStore, if configure dataGroupId in FA mode - * @tc.desc 1.configure dataGroupId in FA mode + * @tc.desc 1.Configure dataGroupId in FA mode * 2.Execute getRdbStore */ it('testRdbStorePromiseTest0006', 0, async function (done) { diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js index 45494e59240f6622c1fb41b2fb53b1ab842b84fb..0e643abcbe24ad7fdac861d34068dcd7aae2499d 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js @@ -50,9 +50,11 @@ describe('rdbStoreExcuteSqlTest', function () { }) /** - * @tc.name resultSet ExcuteSql normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0010 - * @tc.desc resultSet ExcuteSql normal test + * @tc.name Normal test case of ExcuteSql + * @tc.desc 1.Insert data + * 2.ExecuteSql(delete age = "18" OR "20") + * 3.QuerySql */ it('ExcuteSqlTest0001', 0, async function (done) { console.log(TAG + "************* ExcuteSqlTest0001 start *************"); @@ -102,9 +104,11 @@ describe('rdbStoreExcuteSqlTest', function () { }) /** - * @tc.name resultSet ExcuteSql normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0020 - * @tc.desc resultSet ExcuteSql normal test + * @tc.name Normal test case of ExcuteSql + * @tc.desc 1.Insert data + * 2.ExecuteSql(delete name = "lisi") + * 3.QuerySql */ it('ExcuteSqlTest0002', 0, async function (done) { console.log(TAG + "************* ExcuteSqlTest0002 start *************"); @@ -153,9 +157,12 @@ describe('rdbStoreExcuteSqlTest', function () { }) /** - * @tc.name resultSet ExcuteSql normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0030 - * @tc.desc resultSet ExcuteSql normal test + * @tc.name Normal test case of ExcuteSql + * @tc.desc 1.Insert data (param is long string) + * 2.Query data + * 3.ExecuteSql (delete age = 19 AND name = nameStr) + * 4.Query data */ it('ExcuteSqlTest0003', 0, async function (done) { console.log(TAG + "************* ExcuteSqlTest0003 start *************"); @@ -237,9 +244,10 @@ describe('rdbStoreExcuteSqlTest', function () { }) /** - * @tc.name resultSet ExcuteSql normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0040 - * @tc.desc resultSet ExcuteSql normal test + * @tc.name Normal test case of ExcuteSql, drop table + * @tc.desc 1.Insert data + * 2.ExecuteSql (drop table) */ it('ExcuteSqlTest0004', 0, async function (done) { console.log(TAG + "************* ExcuteSqlTest0004 start *************"); diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreTransactionJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreTransactionJsunit.test.js index 416448a27bfe5dde7e500940a41d87cf71b1829d..bd91c48909ab0436b1d8970a6177430cff40f27b 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreTransactionJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreTransactionJsunit.test.js @@ -55,9 +55,12 @@ describe('rdbStoreTransactionTest', function () { console.log(TAG + "*************Unit Test Begin*************"); /** - * @tc.name rdb transaction insert test * @tc.number testRdbTransactionInsert0001 - * @tc.desc rdb transaction insert & commit, the result comes out is 3 items; + * @tc.name Normal test case of transactions, insert a row of data + * @tc.desc 1.Execute beginTransaction + * 2.Insert data + * 3.Execute commit + * 4.Query data */ it('testRdbTransactionInsert0001', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0001 start *************"); @@ -89,9 +92,12 @@ describe('rdbStoreTransactionTest', function () { }) /** - * @tc.name rdb transaction insert test - * @tc.number testRdbTransactionInsert0001 - * @tc.desc rdb transaction insert & commit, the result comes out is 3 items; + * @tc.number testRdbTransactionInsert0002 + * @tc.name Normal test case of transaction, insert three rows of data + * @tc.desc 1.Execute beginTransaction + * 2.Insert data + * 3.Execute commit + * 4.Query data */ it('testRdbTransactionInsert0002', 0, async function (done) { console.log(TAG + "************* testRdbStoreInsert0002 start *************"); @@ -139,10 +145,13 @@ describe('rdbStoreTransactionTest', function () { /** - * @tc.name rdb transaction insert test - * @tc.number testRdbTransactionInsert0002 - * @tc.desc while using transaction to insert values, querying the db, - * the result comes out is 0; + * @tc.number testRdbTransactionInsert0003 + * @tc.name Normal test case of transaction, query data before commit + * @tc.desc 1.Execute beginTransaction + * 2.Insert data + * 3.Query data (expect 0 row) + * 4.Insert data + * 5.Execute commit */ it('testRdbTransactionInsert0003', 0, async function (done) { console.log(TAG + "************* testRdbTransactionInsert0003 start *************"); @@ -187,10 +196,12 @@ describe('rdbStoreTransactionTest', function () { }) /** - * @tc.name rdb insert test - * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0010 - * @tc.desc the classical transaction scenario, when we insert or commit the value, - * db returns an exception, we need to catch exception and rollback. + * @tc.number testRdbTransactionInsert0004 + * @tc.name Abnormal test case of transaction insert, if catch exception then rollback + * @tc.desc 1.Execute beginTransaction + * 2.Insert data (primary key conflict) + * 3.Execute rollBack + * 4.Query data */ it('testRdbTransactionRollBack0001', 0, async function (done) { console.log(TAG + "************* testRdbTransactionRollBack0001 start *************"); @@ -221,10 +232,16 @@ describe('rdbStoreTransactionTest', function () { }) /** - * @tc.name rdb insert test - * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0010 - * @tc.desc the classical transaction scenario, when we insert or commit the value, - * db returns an exception, we need to catch exception and rollback. + * @tc.number testRdbTransactionInsert0005 + * @tc.name Normal test case of transaction, begin transactions within a transaction + * @tc.desc 1.Execute beginTransaction + * 2.Insert data + * 3.Execute beginTransaction + * 4.Insert data + * 5.Execute rollBack + * 6.Insert data + * 7.Execute commit + * 8.Query data */ it('testRdbTransactionMulti0003', 0, async function (done) { console.log(TAG + "************* testRdbTransactionMulti0003 start *************"); diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js index e04ed4d03e6b2024ea55006bac7015524fb363fa..a77989cd034f61f04cc131eb664cd9c9434e00f9 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js @@ -50,9 +50,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0001 - * @tc.desc resultSet Update test + * @tc.name Normal test case of update + * @tc.desc 1.Insert data + * 2.Update data + * 3.Query data */ it('testRdbStoreUpdate0001', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0001 start *************"); @@ -115,9 +117,15 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0002 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update, if TABLE name or Bucket is empty and column invalid + * @tc.desc 1.Create value + * 2.Configure predicates (TABLE name: "") + * 3.Execute update + * 4.Configure predicates (emptyBucket) + * 5.Execute update + * 6.Configure predicates (column: "aaa") + * 7.Execute update */ it('testRdbStoreUpdate0002', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0002 start *************"); @@ -158,9 +166,13 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0003 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update, if TABLE name or Column is invalid + * @tc.desc 1.Create value + * 2.Configure predicates (TABLE name: "wrongTable") + * 3.Execute update + * 4.Configure predicates (column: "wrongColumn") + * 5.Execute update */ it('testRdbStoreUpdate0003', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0003 start *************"); @@ -192,9 +204,13 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0004 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update, if column is invalid + * @tc.desc 1.Create value + * 2.Configure predicates (column: "aaa") + * 3.Execute update + * 4.Configure predicates (column: "null") + * 5.Execute update */ it('testRdbStoreUpdate0004', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0004 start *************"); @@ -229,9 +245,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0005 - * @tc.desc resultSet Update Extra long character test + * @tc.name Normal test case of update, value is long string and special characters + * @tc.desc 1.Insert data + * 2.Update data + * 3.Query data */ it('testRdbStoreUpdate0005', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0005 start *************"); @@ -282,9 +300,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0006 - * @tc.desc resultSet Update Extra long character test + * @tc.name Normal test case of update, value is Chinese and long string + * @tc.desc 1.Insert data + * 2.Update data + * 3.Query data */ it('testRdbStoreUpdate0006', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0006 start *************"); @@ -334,9 +354,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update Extra long character test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0007 - * @tc.desc resultSet Update Extra long character test + * @tc.name Normal test case of update, value is Chinese and long string + * @tc.desc 1.Insert data + * 2.Update data + * 3.Query data */ it('testRdbStoreUpdate0007', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0007 start *************"); @@ -386,9 +408,10 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name rdb update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Update_0008 - * @tc.desc rdb update test + * @tc.name Abnormal test case of update, if non system application calls + * @tc.desc 1.Create value (calling system application) + * 2.Execute update */ it('testRdbStoreUpdate0008', 0, async function () { console.log(TAG + "************* testRdbStoreUpdate0008 start *************"); @@ -410,9 +433,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0001 - * @tc.desc resultSet Update test + * @tc.name Normal test case of update + * @tc.desc 1.Insert data + * 2.Execute update + * 3.Query data */ it('testRdbStoreUpdateWithConflictResolution0001', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0001 start *************"); @@ -509,9 +534,12 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0002 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update with ON_CONFLICT_NONE, if conflict is none + * @tc.desc 1.Insert data + * 2.Create value + * 3.Execute update with ON_CONFLICT_NONE + * 4.Query data */ it('testRdbStoreUpdateWithConflictResolution0002', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0002 start *************"); @@ -609,9 +637,12 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0003 - * @tc.desc resultSet Update test + * @tc.name Normal test case of update with ON_CONFLICT_ROLLBACK + * @tc.desc 1.Insert data + * 2.Create value + * 3.Execute update with ON_CONFLICT_ROLLBACK + * 4.Query data */ it('testRdbStoreUpdateWithConflictResolution0003', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0003 start *************"); @@ -707,9 +738,14 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0004 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update with ON_CONFLICT_ROLLBACK + * @tc.desc 1.Insert data + * 2.Create value + * 3.Begin Transaction + * 4.Insert data + * 5.Update data with ON_CONFLICT_ROLLBACK + * 6.Query data */ it('testRdbStoreUpdateWithConflictResolution0004', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0004 start *************"); @@ -823,9 +859,12 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0005 - * @tc.desc resultSet Update test + * @tc.name Normal test case of insert with ON_CONFLICT_REPLACE + * @tc.desc 1.Insert data + * 2.Create value + * 3.Execute update with ON_CONFLICT_REPLACE + * 4.Query data */ it('testRdbStoreUpdateWithConflictResolution0005', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0005 start *************"); @@ -920,6 +959,14 @@ describe('rdbStoreUpdateTest', function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0005 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0006 + * @tc.name Normal test case of update partial data with ON_CONFLICT_REPLACE + * @tc.desc 1.Insert data + * 2.Create partial value + * 3.Execute update with ON_CONFLICT_REPLACE + * 4.Query data + */ it('testRdbStoreUpdateWithConflictResolution0006', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0006 start *************"); try { @@ -995,9 +1042,11 @@ describe('rdbStoreUpdateTest', function () { }) /** - * @tc.name resultSet Update test * @tc.number SUB_DDM_AppDataFWK_JSRDB_UpdateWithConflictResolution_0007 - * @tc.desc resultSet Update test + * @tc.name Abnormal test case of update, if value of "age" is invalid + * @tc.desc 1.Create value + * 2.Configure predicates + * 3.Execute update */ it('testRdbStoreUpdateWithConflictResolution0007', 0, async function () { console.log(TAG + "************* testRdbStoreUpdateWithConflictResolution0007 start *************"); diff --git a/relational_store/test/native/rdb/unittest/rdb_distributed_test.cpp b/relational_store/test/native/rdb/unittest/rdb_distributed_test.cpp index 1383971fb26c6f978bc6c011ba0ced7091a24edf..5a65dc3320f6ff8f99d3ab219e10fbcc31cef5dc 100644 --- a/relational_store/test/native/rdb/unittest/rdb_distributed_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_distributed_test.cpp @@ -245,10 +245,13 @@ HWTEST_F(RdbStoreDistributedTest, RdbStore_Distributed_Test_005, TestSize.Level2 std::vector tables; // get rdb service succeeded, if configuration file has already been configured - errCode = rdbStore->Sync(option, predicate, nullptr); + errCode = rdbStore->Sync(option, predicate, OHOS::DistributedRdb::AsyncBrief()); EXPECT_EQ(E_OK, errCode); - errCode = rdbStore->Sync(option, tables, nullptr); + errCode = rdbStore->Sync(option, tables, OHOS::DistributedRdb::AsyncDetail()); + EXPECT_EQ(E_OK, errCode); + + errCode = rdbStore->Sync(option, predicate, OHOS::DistributedRdb::AsyncDetail()); EXPECT_EQ(E_OK, errCode); std::string path = RdbStoreDistributedTest::DRDB_PATH + "test.db"; @@ -258,7 +261,7 @@ HWTEST_F(RdbStoreDistributedTest, RdbStore_Distributed_Test_005, TestSize.Level2 EXPECT_NE(nullptr, store); // get rdb service failed, if not configured - errCode = store->Sync(option, predicate, nullptr); + errCode = store->Sync(option, predicate, OHOS::DistributedRdb::AsyncBrief()); EXPECT_EQ(E_INVALID_ARGS, errCode); errCode = store->Sync(option, tables, nullptr); EXPECT_EQ(E_INVALID_ARGS, errCode); diff --git a/relational_store/test/native/rdb/unittest/rdb_encrypt_decrypt_test.cpp b/relational_store/test/native/rdb/unittest/rdb_encrypt_decrypt_test.cpp index 59c2d35ce95ee8da3221d83a4931d5aa7426fb4a..ee0b3d9f6a5f4a3c5882878758532db0def0eaa0 100644 --- a/relational_store/test/native/rdb/unittest/rdb_encrypt_decrypt_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_encrypt_decrypt_test.cpp @@ -276,35 +276,16 @@ HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_06, TestSize.Level1) /** * @tc.name: RdbStore_Encrypt_Decrypt_Test_007 - * @tc.desc: test GetRdbPassword when KeyFileType isNot PUB_KEY_FILE - * @tc.type: FUNC - */ -HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_07, TestSize.Level1) -{ - RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME); - config.SetEncryptStatus(true); - config.SetBundleName("com.example.TestEncrypt7"); - EncryptTestOpenCallback helper; - int errCode; - std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); - EXPECT_NE(store, nullptr); - auto key = RdbSecurityManager::GetInstance().GetRdbPassword(RdbSecurityManager::KeyFileType::PUB_KEY_FILE_NEW_KEY); - RdbPassword password = {}; - EXPECT_NE(key, password); -} - -/** - * @tc.name: RdbStore_Encrypt_Decrypt_Test_008 * @tc.desc: test RemoveSuffix when pos == std::string::npos * @tc.type: FUNC */ -HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_08, TestSize.Level1) +HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_07, TestSize.Level1) { std::string path = RDB_TEST_PATH + "test"; RdbHelper::DeleteRdbStore(path); RdbStoreConfig config(path); config.SetEncryptStatus(true); - config.SetBundleName("com.example.TestEncrypt8"); + config.SetBundleName("com.example.TestEncrypt7"); EncryptTestOpenCallback helper; int errCode; std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); @@ -315,11 +296,11 @@ HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_08, TestSize.Level1) } /** - * @tc.name: RdbStore_Encrypt_Decrypt_Test_009 + * @tc.name: RdbStore_Encrypt_Decrypt_Test_008 * @tc.desc: test RdbStore Get Encrypt Store without SetBundleName * @tc.type: FUNC */ -HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_009, TestSize.Level1) +HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_008, TestSize.Level1) { RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME); config.SetEncryptStatus(true); diff --git a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp index bff6ecb0385dcf5744aa32cf07363f261b1eaeeb..a49a713ae3bbdad18a537282c3169009d8654ede 100644 --- a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp @@ -38,6 +38,8 @@ public: void GenerateDefaultTable(); void GenerateAssetsTable(); void GenerateTimeoutTable(); + void CheckResultSetAttribute(std::shared_ptr rstSet, int pos, bool isStart, bool isAtFirstRow, + bool isEnded); static const std::string DATABASE_NAME; static std::shared_ptr store; @@ -174,6 +176,30 @@ void RdbSqliteSharedResultSetTest::GenerateTimeoutTable() store->Insert(id, "test", values); } +void RdbSqliteSharedResultSetTest::CheckResultSetAttribute(std::shared_ptr rstSet, int pos, bool isStart, + bool isAtFirstRow, bool isEnded) +{ + int position = -1; + int iRet = rstSet->GetRowIndex(position); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(pos, position); + + bool bResultSet = !isStart; + iRet = rstSet->IsStarted(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isStart, bResultSet); + + bResultSet = !isAtFirstRow; + iRet = rstSet->IsAtFirstRow(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isAtFirstRow, bResultSet); + + bResultSet = !isEnded; + iRet = rstSet->IsEnded(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isEnded, bResultSet); +} + /* * * @tc.name: Sqlite_Shared_Result_Set_Asset_Timeout * @tc.desc: normal testcase of SqliteSharedResultSet for move @@ -382,76 +408,25 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_002, TestSize.Le RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); EXPECT_NE(rstSet, nullptr); - int pos = -2; - rstSet->GetRowIndex(pos); - EXPECT_EQ(pos, -1); - bool isStart = true; - rstSet->IsStarted(isStart); - EXPECT_EQ(isStart, false); - bool isAtFirstRow = true; - rstSet->IsAtFirstRow(isAtFirstRow); - EXPECT_EQ(isAtFirstRow, false); - bool isEnded = true; - rstSet->IsEnded(isEnded); - EXPECT_EQ(isEnded, false); + CheckResultSetAttribute(rstSet, -1, false, false, false); - int retN1 = rstSet->GoToNextRow(); - EXPECT_EQ(retN1, E_OK); - rstSet->GetRowIndex(pos); - EXPECT_EQ(pos, 0); - rstSet->IsStarted(isStart); - EXPECT_EQ(isStart, true); - rstSet->IsAtFirstRow(isAtFirstRow); - EXPECT_EQ(isAtFirstRow, true); - isEnded = true; - rstSet->IsEnded(isEnded); - EXPECT_EQ(isEnded, false); - - int retN2 = rstSet->GoToNextRow(); - EXPECT_EQ(retN2, E_OK); - rstSet->GetRowIndex(pos); - EXPECT_EQ(pos, 1); - isStart = false; - rstSet->IsStarted(isStart); - EXPECT_EQ(isStart, true); - isAtFirstRow = true; - rstSet->IsAtFirstRow(isAtFirstRow); - EXPECT_EQ(isAtFirstRow, false); - isEnded = true; - rstSet->IsEnded(isEnded); - EXPECT_EQ(isEnded, false); - - int retN3 = rstSet->GoToNextRow(); - EXPECT_EQ(retN3, E_OK); - rstSet->GetRowIndex(pos); - EXPECT_EQ(pos, 2); - isStart = false; - rstSet->IsStarted(isStart); - EXPECT_EQ(isStart, true); - isAtFirstRow = true; - rstSet->IsAtFirstRow(isAtFirstRow); - EXPECT_EQ(isAtFirstRow, false); + EXPECT_EQ(rstSet->GoToNextRow(), E_OK); + CheckResultSetAttribute(rstSet, 0, true, true, false); + + EXPECT_EQ(rstSet->GoToNextRow(), E_OK); + CheckResultSetAttribute(rstSet, 1, true, false, false); + + EXPECT_EQ(rstSet->GoToNextRow(), E_OK); + CheckResultSetAttribute(rstSet, 2, true, false, false); bool isAtLastRow = false; rstSet->IsAtLastRow(isAtLastRow); EXPECT_EQ(isAtLastRow, true); - - int retN = rstSet->GoToNextRow(); - EXPECT_EQ(retN, E_ERROR); - rstSet->GetRowIndex(pos); - EXPECT_EQ(pos, 3); - isStart = false; - rstSet->IsStarted(isStart); - EXPECT_EQ(isStart, true); - isAtFirstRow = true; - rstSet->IsAtFirstRow(isAtFirstRow); - EXPECT_EQ(isAtFirstRow, false); - isEnded = false; - rstSet->IsEnded(isEnded); - EXPECT_EQ(isEnded, true); + + EXPECT_EQ(rstSet->GoToNextRow(), E_ERROR); + CheckResultSetAttribute(rstSet, 3, true, false, true); rstSet->Close(); - bool isClosedFlag = rstSet->IsClosed(); - EXPECT_EQ(isClosedFlag, true); + EXPECT_EQ(rstSet->IsClosed(), true); } /* * diff --git a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp index 20ac61008aad9b17ede756ccb50bd2aa9776a42a..2c144c7dc1c4ac2e1093388270dd7c047b72e7fd 100644 --- a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp @@ -27,6 +27,19 @@ using namespace testing::ext; using namespace OHOS::NativeRdb; +struct ResultSetData { + std::string strValue; + int iValue; + double dValue; + std::vector blobValue; +}; + +ResultSetData g_resultSetData[3] = { + {"2", -5, 2.5, std::vector{}}, + {"hello", 10, 1.0, std::vector{ 66 }}, + {"hello world", 3, 1.8, std::vector{}} +}; + class RdbStepResultSetTest : public testing::Test { public: static void SetUpTestCase(void); @@ -35,6 +48,10 @@ public: void TearDown(); void GenerateDefaultTable(); void GenerateDefaultEmptyTable(); + void CheckColumnType(std::shared_ptr resultSet, int columnIndex, ColumnType type); + void CheckResultSetAttribute(std::shared_ptr resultSet, int pos, bool isStart, bool isAtFirstRow, + bool isEnded); + void CheckResultSetData(int columnIndex, std::shared_ptr resultSet, ResultSetData &rowData); static const std::string DATABASE_NAME; static std::shared_ptr store; @@ -124,6 +141,66 @@ void RdbStepResultSetTest::GenerateDefaultEmptyTable() store->ExecuteSql(createTableSql); } +void RdbStepResultSetTest::CheckColumnType(std::shared_ptr resultSet, int columnIndex, ColumnType type) +{ + ColumnType columnType; + int iRet = resultSet->GetColumnType(columnIndex, columnType); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(columnType, type); +} + +void RdbStepResultSetTest::CheckResultSetAttribute(std::shared_ptr resultSet, int pos, bool isStart, + bool isAtFirstRow, bool isEnded) +{ + int position = -1; + int iRet = resultSet->GetRowIndex(position); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(pos, position); + + bool bResultSet = !isStart; + iRet = resultSet->IsStarted(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isStart, bResultSet); + + bResultSet = !isAtFirstRow; + iRet = resultSet->IsAtFirstRow(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isAtFirstRow, bResultSet); + + bResultSet = !isEnded; + iRet = resultSet->IsEnded(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(isEnded, bResultSet); +} + +void RdbStepResultSetTest::CheckResultSetData( + int columnIndex, std::shared_ptr resultSet, ResultSetData &resultSetData) +{ + std::string strValue; + int iValue; + double dValue; + std::vector blobValue; + + int iRet = resultSet->GetString(columnIndex, strValue); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(resultSetData.strValue, strValue); + + iRet = resultSet->GetInt(++columnIndex, iValue); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(resultSetData.iValue, iValue); + + iRet = resultSet->GetDouble(++columnIndex, dValue); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(resultSetData.dValue, dValue); + + iRet = resultSet->GetBlob(++columnIndex, blobValue); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(resultSetData.blobValue.size(), blobValue.size()); + for (int i = 0; i < blobValue.size(); i++) { + EXPECT_EQ(resultSetData.blobValue[i], blobValue[i]); + } +} + /* * * @tc.name: RdbStore_StepResultSet_001 * @tc.desc: test StepResultSet @@ -147,26 +224,15 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_001, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(bResultSet, true); - ColumnType type; - iRet = resultSet->GetColumnType(0, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_INTEGER, type); + CheckColumnType(resultSet, 0, ColumnType::TYPE_INTEGER); - iRet = resultSet->GetColumnType(1, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_STRING, type); + CheckColumnType(resultSet, 1, ColumnType::TYPE_STRING); - iRet = resultSet->GetColumnType(2, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_INTEGER, type); + CheckColumnType(resultSet, 2, ColumnType::TYPE_INTEGER); - iRet = resultSet->GetColumnType(3, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_FLOAT, type); + CheckColumnType(resultSet, 3, ColumnType::TYPE_FLOAT); - iRet = resultSet->GetColumnType(4, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_BLOB, type); + CheckColumnType(resultSet, 4, ColumnType::TYPE_BLOB); EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); EXPECT_EQ(E_OK, resultSet->GoToNextRow()); @@ -180,24 +246,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_001, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(3, count); - std::string stringValue; - iRet = resultSet->GetString(1, stringValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("2", stringValue); - - int iValue; - iRet = resultSet->GetInt(2, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-5, iValue); - - double dValue; - iRet = resultSet->GetDouble(3, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(2.5, dValue); - - std::vector blobValue; - iRet = resultSet->GetBlob(4, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(1, resultSet, g_resultSetData[0]); } /* * @@ -268,50 +317,16 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_003, TestSize.Level1) std::shared_ptr resultSet = store->QueryByStep("SELECT * FROM test"); EXPECT_NE(resultSet, nullptr); - int position = INT_MIN; - bool bResultSet = true; - int iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); - - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = true; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = true; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + CheckResultSetAttribute(resultSet, -1, false, false, false); int moveTimes = 0; EXPECT_EQ(E_OK, resultSet->GoToNextRow()); moveTimes++; - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 0, true, true, false); - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = true; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - iRet = resultSet->GetRowIndex(position); + int position = INT_MIN; + int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(0, position); while (E_OK == resultSet->GoToNextRow()) { @@ -319,24 +334,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_003, TestSize.Level1) } /* Cursor is before first */ - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, position); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = true; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = false; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 3, true, false, true); } /* * @@ -351,36 +349,16 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_004, TestSize.Level1) std::shared_ptr resultSet = store->QueryByStep("SELECT data1, data2, data3, data4 FROM test"); EXPECT_NE(resultSet, nullptr); - int position = INT_MIN; - bool bResultSet = true; - int iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); - - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = true; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + CheckResultSetAttribute(resultSet, -1, false, false, false); EXPECT_NE(E_OK, resultSet->GoToNextRow()); - iRet = resultSet->GetRowIndex(position); + int position = INT_MIN; + int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(0, position); - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 0, true, true, true); } /* * @@ -397,41 +375,16 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_005, TestSize.Level1) EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); - int position = INT_MIN; - bool bResultSet = false; - int iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); - - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 0, true, true, false); EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); - - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 0, true, true, false); EXPECT_EQ(E_OK, resultSet->GoToNextRow()); EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); + bool bResultSet = false; + int iRet = resultSet->IsAtFirstRow(bResultSet); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(bResultSet, true); @@ -455,26 +408,13 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_006, TestSize.Level1) EXPECT_NE(E_OK, resultSet->GoToFirstRow()); - int position = INT_MIN; - bool bResultSet = false; - int iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); - - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 0, true, true, true); EXPECT_NE(E_OK, resultSet->GoToNextRow()); EXPECT_NE(E_OK, resultSet->GoToFirstRow()); - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); + bool bResultSet = false; + int iRet = resultSet->IsAtFirstRow(bResultSet); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(bResultSet, true); @@ -790,25 +730,15 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_013, TestSize.Level1) EXPECT_NE(E_OK, iRet); EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); - iRet = resultSet->GetColumnType(0, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_INTEGER, type); - - iRet = resultSet->GetColumnType(1, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_STRING, type); - - iRet = resultSet->GetColumnType(2, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_INTEGER, type); + CheckColumnType(resultSet, 0, ColumnType::TYPE_INTEGER); - iRet = resultSet->GetColumnType(3, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_FLOAT, type); + CheckColumnType(resultSet, 1, ColumnType::TYPE_STRING); - iRet = resultSet->GetColumnType(4, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_BLOB, type); + CheckColumnType(resultSet, 2, ColumnType::TYPE_INTEGER); + + CheckColumnType(resultSet, 3, ColumnType::TYPE_FLOAT); + + CheckColumnType(resultSet, 4, ColumnType::TYPE_BLOB); int columnCount = 0; iRet = resultSet->GetColumnCount(columnCount); @@ -953,37 +883,10 @@ HWTEST_F(RdbStepResultSetTest, testGetRowCount003, TestSize.Level1) EXPECT_EQ(E_OK, resultSet->GoToNextRow()); bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(E_OK, resultSet->IsAtFirstRow(bResultSet)); EXPECT_EQ(bResultSet, true); - std::string strValue; - iRet = resultSet->GetString(1, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello", strValue); - - int iValue; - iRet = resultSet->GetInt(2, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(10, iValue); - - double dValue; - iRet = resultSet->GetDouble(3, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.0, dValue); - - std::vector blobValue; - iRet = resultSet->GetBlob(4, blobValue); - EXPECT_EQ(E_OK, iRet); - - std::string strBlob; - strBlob.clear(); - for (size_t i = 0; i < blobValue.size(); i++) { - strBlob += char(blobValue[i]); - } - char cValue = 66; - string strTmpValue(1, cValue); - EXPECT_EQ(strTmpValue, strBlob); + CheckResultSetData(1, resultSet, g_resultSetData[1]); iRet = resultSet->GetRowCount(count); EXPECT_EQ(E_OK, iRet); @@ -995,20 +898,7 @@ HWTEST_F(RdbStepResultSetTest, testGetRowCount003, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(1, position); - iRet = resultSet->GetString(1, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("2", strValue); - - iRet = resultSet->GetInt(2, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-5, iValue); - - iRet = resultSet->GetDouble(3, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(2.5, dValue); - - iRet = resultSet->GetBlob(4, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(1, resultSet, g_resultSetData[0]); EXPECT_EQ(E_OK, resultSet->GoToNextRow()); iRet = resultSet->GetRowIndex(position); @@ -1048,33 +938,7 @@ HWTEST_F(RdbStepResultSetTest, testGetRowCount004, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(3, count); - std::string strValue; - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello", strValue); - - int iValue; - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(10, iValue); - - double dValue; - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.0, dValue); - - std::vector blobValue; - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); - - std::string strBlob; - strBlob.clear(); - for (size_t i = 0; i < blobValue.size(); i++) { - strBlob += char(blobValue[i]); - } - char cValue = 66; - string strTmpValue(1, cValue); - EXPECT_EQ(strTmpValue, strBlob); + CheckResultSetData(0, resultSet, g_resultSetData[1]); EXPECT_EQ(E_OK, resultSet->GoToNextRow()); @@ -1093,20 +957,7 @@ HWTEST_F(RdbStepResultSetTest, testGetRowCount004, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(3, count); - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello world", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.8, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(0, resultSet, g_resultSetData[2]); } /* * @@ -1143,24 +994,7 @@ HWTEST_F(RdbStepResultSetTest, testGoToRow005, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(2, position); - std::string strValue; - int iValue; - double dValue; - std::vector blobValue; - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello world", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.8, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(0, resultSet, g_resultSetData[2]); EXPECT_EQ(E_OK, resultSet->GoToRow(1)); @@ -1168,21 +1002,7 @@ HWTEST_F(RdbStepResultSetTest, testGoToRow005, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(1, position); - - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("2", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-5, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(2.5, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(0, resultSet, g_resultSetData[0]); } /* * @@ -1214,24 +1034,7 @@ HWTEST_F(RdbStepResultSetTest, testGo006, TestSize.Level1) EXPECT_EQ(resultSet->GoTo(2), E_OK); - std::string strValue; - int iValue; - double dValue; - std::vector blobValue; - iRet = resultSet->GetString(1, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello world", strValue); - - iRet = resultSet->GetInt(2, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, iValue); - - iRet = resultSet->GetDouble(3, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.8, dValue); - - iRet = resultSet->GetBlob(4, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(1, resultSet, g_resultSetData[2]); EXPECT_EQ(resultSet->GoTo(-2), E_OK); @@ -1239,29 +1042,7 @@ HWTEST_F(RdbStepResultSetTest, testGo006, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(0, position); - iRet = resultSet->GetString(1, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello", strValue); - - iRet = resultSet->GetInt(2, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(10, iValue); - - iRet = resultSet->GetDouble(3, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.0, dValue); - - iRet = resultSet->GetBlob(4, blobValue); - EXPECT_EQ(E_OK, iRet); - - std::string strBlob; - strBlob.clear(); - for (size_t i = 0; i < blobValue.size(); i++) { - strBlob += char(blobValue[i]); - } - char cValue = 66; - string strTmpValue(1, cValue); - EXPECT_EQ(strTmpValue, strBlob); + CheckResultSetData(1, resultSet, g_resultSetData[1]); } /* * @@ -1293,88 +1074,33 @@ HWTEST_F(RdbStepResultSetTest, testGoToPrevious007, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(bResultSet, true); - std::string strValue; - int iValue; - double dValue; - std::vector blobValue; - - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("hello", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(10, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(1.0, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); - - std::string strBlob; - strBlob.clear(); - for (size_t i = 0; i < blobValue.size(); i++) { - strBlob += char(blobValue[i]); - } - char cValue = 66; - string strTmpValue(1, cValue); - EXPECT_EQ(strTmpValue, strBlob); + CheckResultSetData(0, resultSet, g_resultSetData[1]); int ret = resultSet->GoToPreviousRow(); EXPECT_NE(E_OK, ret); - int position = INT_MIN; - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); - - bResultSet = true; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + CheckResultSetAttribute(resultSet, -1, false, false, false); EXPECT_EQ(resultSet->GoTo(2), E_OK); - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("2", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-5, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(2.5, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(0, resultSet, g_resultSetData[0]); EXPECT_EQ(E_OK, resultSet->GoToLastRow()); - bResultSet = false; - iRet = resultSet->IsAtLastRow(bResultSet); + iRet = resultSet->IsAtLastRow(bResultSet); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(true, bResultSet); EXPECT_EQ(E_OK, resultSet->GoToPreviousRow()); + int position = INT_MIN; iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); EXPECT_EQ(1, position); EXPECT_NE(E_OK, resultSet->GoTo(3)); - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, position); - - bResultSet = false; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 3, true, false, true); } /* * @@ -1401,22 +1127,13 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep008, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(bResultSet, true); - ColumnType type; - iRet = resultSet->GetColumnType(0, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_STRING, type); + CheckColumnType(resultSet, 0, ColumnType::TYPE_STRING); - iRet = resultSet->GetColumnType(1, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_INTEGER, type); + CheckColumnType(resultSet, 1, ColumnType::TYPE_INTEGER); - iRet = resultSet->GetColumnType(2, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_FLOAT, type); + CheckColumnType(resultSet, 2, ColumnType::TYPE_FLOAT); - iRet = resultSet->GetColumnType(3, type); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(ColumnType::TYPE_BLOB, type); + CheckColumnType(resultSet, 3, ColumnType::TYPE_BLOB); EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); EXPECT_EQ(E_OK, resultSet->GoToNextRow()); @@ -1431,25 +1148,7 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep008, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(3, count); - std::string strValue; - int iValue; - double dValue; - std::vector blobValue; - - iRet = resultSet->GetString(0, strValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ("2", strValue); - - iRet = resultSet->GetInt(1, iValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-5, iValue); - - iRet = resultSet->GetDouble(2, dValue); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(2.5, dValue); - - iRet = resultSet->GetBlob(3, blobValue); - EXPECT_EQ(E_OK, iRet); + CheckResultSetData(0, resultSet, g_resultSetData[0]); } /* * @@ -1527,70 +1226,19 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep010, TestSize.Level1) std::shared_ptr resultSet = store->QueryByStep("SELECT data1, data2, data3, data4 FROM test"); EXPECT_NE(resultSet, nullptr); - int position = INT_MIN; - int iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); - bool bResultSet = true; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = true; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = true; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + CheckResultSetAttribute(resultSet, -1, false, false, false); int moveTimes = 0; EXPECT_EQ(E_OK, resultSet->GoToNextRow()); moveTimes++; - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = false; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = true; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + CheckResultSetAttribute(resultSet, 0, true, true, false); while (E_OK == resultSet->GoToNextRow()) { moveTimes++; } - iRet = resultSet->GetRowIndex(position); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(3, position); - - bResultSet = false; - iRet = resultSet->IsStarted(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); - - bResultSet = true; - iRet = resultSet->IsAtFirstRow(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); - - bResultSet = false; - iRet = resultSet->IsEnded(bResultSet); - EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + CheckResultSetAttribute(resultSet, 3, true, false, true); } /* * @@ -1730,7 +1378,7 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep014, TestSize.Level1) std::shared_ptr resultSet5 = store->QueryByStep("SELECT * FROM test"); EXPECT_NE(resultSet2, nullptr); - EXPECT_EQ(E_CON_OVER_LIMIT, resultSet5->GoToRow(1)); + EXPECT_EQ(E_OK, resultSet5->GoToRow(1)); EXPECT_EQ(E_OK, resultSet1->Close()); EXPECT_EQ(E_OK, resultSet2->Close()); diff --git a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp index 577a3e799cf18d06a84239084f9ed252306b12dd..04bc93e6d5144953f49b219e11cb1dc37677a440 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp @@ -853,47 +853,16 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_027, TestSize.Level1) EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); - std::shared_ptr resultSet1 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet1, nullptr); - EXPECT_EQ(E_OK, resultSet1->GoToFirstRow()); - std::shared_ptr resultSet2 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet2, nullptr); - EXPECT_EQ(E_OK, resultSet2->GoToFirstRow()); - std::shared_ptr resultSet3 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet3, nullptr); - EXPECT_EQ(E_OK, resultSet3->GoToFirstRow()); - std::shared_ptr resultSet4 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet4, nullptr); - EXPECT_EQ(E_OK, resultSet4->GoToFirstRow()); - std::shared_ptr resultSet5 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet5, nullptr); - EXPECT_EQ(E_OK, resultSet5->GoToFirstRow()); - std::shared_ptr resultSet6 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet6, nullptr); - EXPECT_EQ(E_OK, resultSet6->GoToFirstRow()); - std::shared_ptr resultSet7 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet7, nullptr); - EXPECT_EQ(E_OK, resultSet7->GoToFirstRow()); - std::shared_ptr resultSet8 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet8, nullptr); - EXPECT_EQ(E_OK, resultSet8->GoToFirstRow()); - std::shared_ptr resultSet9 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet9, nullptr); - EXPECT_EQ(E_OK, resultSet9->GoToFirstRow()); - std::shared_ptr resultSet10 = store->QueryByStep("SELECT * FROM test"); - EXPECT_NE(resultSet10, nullptr); - EXPECT_EQ(E_OK, resultSet10->GoToFirstRow()); - - EXPECT_EQ(E_OK, resultSet1->Close()); - EXPECT_EQ(E_OK, resultSet2->Close()); - EXPECT_EQ(E_OK, resultSet3->Close()); - EXPECT_EQ(E_OK, resultSet4->Close()); - EXPECT_EQ(E_OK, resultSet5->Close()); - EXPECT_EQ(E_OK, resultSet6->Close()); - EXPECT_EQ(E_OK, resultSet7->Close()); - EXPECT_EQ(E_OK, resultSet8->Close()); - EXPECT_EQ(E_OK, resultSet9->Close()); - EXPECT_EQ(E_OK, resultSet10->Close()); + std::vector> resultSets; + for (int i = 0; i < readConSize; ++i) { + auto resultSet = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + resultSets.push_back(resultSet); + } + for (const auto &resultSet: resultSets) { + EXPECT_EQ(E_OK, resultSet->Close()); + } } /** diff --git a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp index 6832d09a452306a38cbd74decc668c417d453978..e7a68a822fb6f624f3d0f3eefe78c5af93d8090e 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp @@ -58,10 +58,13 @@ int RdbStoreImplTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int return E_OK; } -void RdbStoreImplTest::SetUpTestCase(void) +void RdbStoreImplTest::SetUpTestCase(void) {} + +void RdbStoreImplTest::TearDownTestCase(void) {} + +void RdbStoreImplTest::SetUp(void) { int errCode = E_OK; - RdbHelper::DeleteRdbStore(DATABASE_NAME); RdbStoreConfig config(RdbStoreImplTest::DATABASE_NAME); RdbStoreImplTestOpenCallback helper; RdbStoreImplTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode); @@ -69,17 +72,13 @@ void RdbStoreImplTest::SetUpTestCase(void) EXPECT_EQ(errCode, E_OK); } -void RdbStoreImplTest::TearDownTestCase(void) +void RdbStoreImplTest::TearDown(void) { RdbHelper::ClearCache(); - RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); + int errCode = RdbHelper::DeleteRdbStore(RdbStoreImplTest::DATABASE_NAME); + EXPECT_EQ(E_OK, errCode); } -void RdbStoreImplTest::SetUp(void) {} - -void RdbStoreImplTest::TearDown(void) {} - - /* * * @tc.name: GetModifyTimeByRowIdTest_001 * @tc.desc: Normal testCase for GetModifyTime, get timestamp by id @@ -99,8 +98,9 @@ HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_001, TestSize.Level2) EXPECT_EQ(E_OK, errorCode); EXPECT_EQ(1, rowId); - std::vector PKey = {1}; - auto result = RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey); + std::vector PKey = { 1 }; + std::map result = + RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey); int size = result.size(); EXPECT_EQ(1, size); EXPECT_EQ(100000, int64_t(result[1])); @@ -108,7 +108,6 @@ HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_001, TestSize.Level2) RdbStoreImplTest::store->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log"); } - /* * * @tc.name: GetModifyTimeByRowIdTest_002 * @tc.desc: Abnormal testCase for GetModifyTime, get timestamp by id, @@ -118,8 +117,8 @@ HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_001, TestSize.Level2) HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_002, TestSize.Level2) { RdbStoreImplTest::store->ExecuteSql("CREATE TABLE naturalbase_rdb_aux_rdbstoreimpltest_integer_log " - "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, " - "data3 FLOAT, data4 BLOB, data5 BOOLEAN);"); + "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, " + "data3 FLOAT, data4 BLOB, data5 BOOLEAN);"); int64_t rowId; ValuesBucket valuesBucket; valuesBucket.PutInt("data_key", ValueObject(2)); @@ -129,8 +128,9 @@ HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_002, TestSize.Level2) EXPECT_EQ(1, rowId); // resultSet is empty - std::vector PKey = {1}; - auto result = RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey); + std::vector PKey = { 1 }; + std::map result = + RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "ROWID", PKey); int size = result.size(); EXPECT_EQ(0, size); @@ -191,9 +191,9 @@ HWTEST_F(RdbStoreImplTest, GetModifyTime_002, TestSize.Level2) "data3 FLOAT, data4 BLOB, data5 BOOLEAN);"); std::vector PKey = {1}; - auto result = RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "data3", PKey); - int size = result.size(); - EXPECT_EQ(0, size); + std::map result = + RdbStoreImplTest::store->GetModifyTime("rdbstoreimpltest_integer", "data3", PKey); + EXPECT_EQ(0, result.size()); RdbStoreImplTest::store->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log"); } @@ -238,7 +238,7 @@ HWTEST_F(RdbStoreImplTest, Rdb_QueryTest_002, TestSize.Level2) RdbStoreImplTest::store->Query(errCode, true, "test", {}, "", std::vector {}, "", "", "", 1, 0); EXPECT_EQ(E_OK, errCode); - + store->ExecuteSql("DROP TABLE IF EXISTS test"); } diff --git a/relational_store/test/native/rdb/unittest/rdb_transaction_test.cpp b/relational_store/test/native/rdb/unittest/rdb_transaction_test.cpp index bec8085b31dd0f9785199f6ab5e355478d139a1c..105f5b9b2c49330652032b8ec423697cac12a5e8 100644 --- a/relational_store/test/native/rdb/unittest/rdb_transaction_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_transaction_test.cpp @@ -89,6 +89,31 @@ void RdbTransactionTest::TearDown(void) { } +struct RowData { + int id; + string name; + int age; + double salary; + std::vector blobType; +}; + +static RowData g_rowData[3] = { + {1, "zhangsan", 18, 100.5, std::vector{ 1, 2, 3 }}, + {2, "lisi", 19, 200.5, std::vector{ 4, 5, 6 }}, + {3, "wangyjing", 20, 300.5, std::vector{ 7, 8, 9 }} +}; + +static ValuesBucket InsertRowData(const RowData &rowData) +{ + ValuesBucket value; + value.PutInt("id", rowData.id); + value.PutString("name", rowData.name); + value.PutInt("age", rowData.age); + value.PutDouble("salary", rowData.salary); + value.PutBlob("blobType", rowData.blobType); + return value; +} + /** * @tc.name: RdbStore_Transaction_001 * @tc.desc: test RdbStore BaseTransaction @@ -99,37 +124,18 @@ HWTEST_F(RdbTransactionTest, RdbStore_Transaction_001, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -157,37 +163,18 @@ HWTEST_F(RdbTransactionTest, RdbStore_Transaction_002, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -223,37 +210,18 @@ HWTEST_F(RdbTransactionTest, RdbStore_Transaction_003, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -287,41 +255,22 @@ HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_001, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); ret = store->Commit(); // not commit EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -356,29 +305,16 @@ HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_002, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); ret = store->Commit(); @@ -386,13 +322,7 @@ HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_002, TestSize.Level1) ret = store->Commit(); // commit EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -424,41 +354,22 @@ HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_003, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); ret = store->Commit(); // not commit EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -493,41 +404,22 @@ HWTEST_F(RdbTransactionTest, RdbStore_NestedTransaction_004, TestSize.Level1) std::shared_ptr &store = RdbTransactionTest::store; int64_t id; - ValuesBucket values; - int ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.PutInt("id", 1); - values.PutString("name", std::string("zhangsan")); - values.PutInt("age", 18); - values.PutDouble("salary", 100.5); - values.PutBlob("blobType", std::vector{ 1, 2, 3 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[0])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(1, id); ret = store->BeginTransaction(); EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 2); - values.PutString("name", std::string("lisi")); - values.PutInt("age", 19); - values.PutDouble("salary", 200.5); - values.PutBlob("blobType", std::vector{ 4, 5, 6 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[1])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(2, id); ret = store->Commit(); // commit EXPECT_EQ(ret, E_OK); - values.Clear(); - values.PutInt("id", 3); - values.PutString("name", std::string("wangyjing")); - values.PutInt("age", 20); - values.PutDouble("salary", 300.5); - values.PutBlob("blobType", std::vector{ 7, 8, 9 }); - ret = store->Insert(id, "test", values); + ret = store->Insert(id, "test", InsertRowData(g_rowData[2])); EXPECT_EQ(ret, E_OK); EXPECT_EQ(3, id); @@ -643,12 +535,8 @@ HWTEST_F(RdbTransactionTest, RdbStore_BatchInsert_003, TestSize.Level1) std::vector blob = { 1, 2, 3 }; std::vector valuesBuckets; for (int i = 0; i < 100; i++) { - ValuesBucket values; - values.PutInt("id", id + i); - values.PutString("name", name); - values.PutInt("age", age + i); - values.PutDouble("salary", salary + i); - values.PutBlob("blobType", blob); + RowData rowData1 = {id + i, name, age + i, salary + i, blob}; + ValuesBucket values = InsertRowData(rowData1); valuesBuckets.push_back(std::move(values)); } @@ -664,12 +552,8 @@ HWTEST_F(RdbTransactionTest, RdbStore_BatchInsert_003, TestSize.Level1) valuesBuckets.clear(); for (int i = 50; i < 100; i++) { - ValuesBucket values; - values.PutInt("id", id + i); - values.PutString("name", name); - values.PutInt("age", age + i); - values.PutDouble("salary", salary + i); - values.PutBlob("blobType", blob); + RowData rowData2 = {id + i, name, age + i, salary + i, blob}; + ValuesBucket values = InsertRowData(rowData2); valuesBuckets.push_back(std::move(values)); } diff --git a/relational_store/test/ndk/BUILD.gn b/relational_store/test/ndk/BUILD.gn index aa491d594daf848ab155c2852160a4699c73ec12..0de7a9ae44285643af9e1eec63f412704ef60473 100644 --- a/relational_store/test/ndk/BUILD.gn +++ b/relational_store/test/ndk/BUILD.gn @@ -20,6 +20,7 @@ config("module_private_config") { visibility = [ ":*" ] include_dirs = [ + "${kvstore_path}/common", "${relational_store_base_path}/interfaces/ndk/include", "${relational_store_innerapi_path}/rdb/include", "${relational_store_innerapi_path}/appdatafwk/include", @@ -33,6 +34,7 @@ ohos_unittest("NativeRdbNdkTest") { module_out_path = module_output_path sources = [ + "${relational_store_base_path}/interfaces/ndk/src/relational_asset.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_cursor.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_predicates.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_predicates_objects.cpp", @@ -46,6 +48,8 @@ ohos_unittest("NativeRdbNdkTest") { configs = [ ":module_private_config" ] external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", "c_utils:utils", "hilog:libhilog", ] diff --git a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp index c0e152f1ed85df34672a054bbe1deb7cd94ffb24..41aa1140c4b3c35776b54e1a24eee493662cde57 100644 --- a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp @@ -14,10 +14,10 @@ */ #include - #include #include #include + #include "common.h" #include "relational_store.h" #include "relational_store_error_code.h" @@ -39,13 +39,16 @@ public: config_.moduleName = ""; config_.securityLevel = OH_Rdb_SecurityLevel::S1; config_.isEncrypt = false; + config_.area = Rdb_SecurityArea::RDB_SECURITY_AREA_EL1; config_.selfSize = sizeof(OH_Rdb_Config); } + static void CreateAssetTable(); + static void SetAsset(Data_Asset *asset, int index); static OH_Rdb_Config config_; }; OH_Rdb_Store *cursorTestRdbStore_; -OH_Rdb_Config RdbNativeCursorTest::config_ = {0}; +OH_Rdb_Config RdbNativeCursorTest::config_ = { 0 }; void RdbNativeCursorTest::SetUpTestCase(void) { InitRdbConfig(); @@ -63,7 +66,7 @@ void RdbNativeCursorTest::SetUpTestCase(void) valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); @@ -89,6 +92,7 @@ void RdbNativeCursorTest::SetUpTestCase(void) EXPECT_EQ(errCode, 3); valueBucket->destroy(valueBucket); + CreateAssetTable(); } void RdbNativeCursorTest::TearDownTestCase(void) @@ -98,12 +102,75 @@ void RdbNativeCursorTest::TearDownTestCase(void) OH_Rdb_DeleteStore(&config_); } -void RdbNativeCursorTest::SetUp(void) +void RdbNativeCursorTest::SetUp(void) {} + +void RdbNativeCursorTest::TearDown(void) {} + +void RdbNativeCursorTest::CreateAssetTable() { + char createTableSql[] = "CREATE TABLE IF NOT EXISTS asset_table (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 " + "asset, data2 assets );"; + int errCode = OH_Rdb_Execute(cursorTestRdbStore_, createTableSql); + EXPECT_EQ(errCode, RDB_OK); + char table[] = "asset_table"; + int assetsCount = 2; + int curRow = 1; + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); + Data_Asset *asset1 = OH_Data_Asset_CreateOne(); + SetAsset(asset1, 1); + Data_Asset *asset2 = OH_Data_Asset_CreateOne(); + SetAsset(asset2, 2); + + valueBucket->putInt64(valueBucket, "id", curRow); + OH_VBucket_PutAsset(valueBucket, "data1", asset1); + Data_Asset **assets1 = OH_Data_Asset_CreateMultiple(assetsCount); + SetAsset(assets1[0], 1); + SetAsset(assets1[1], 2); + errCode = OH_VBucket_PutAssets(valueBucket, "data2", assets1, assetsCount); + int rowID = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket); + EXPECT_EQ(rowID, curRow); + curRow++; + + valueBucket->clear(valueBucket); + valueBucket->putInt64(valueBucket, "id", curRow); + OH_VBucket_PutAsset(valueBucket, "data1", asset2); + Data_Asset **assets2 = OH_Data_Asset_CreateMultiple(assetsCount); + SetAsset(assets2[0], 1); + SetAsset(assets2[1], 3); + errCode = OH_VBucket_PutAssets(valueBucket, "data2", assets2, assetsCount); + rowID = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket); + EXPECT_EQ(rowID, curRow); + + OH_Data_Asset_DestroyMultiple(assets1, assetsCount); + OH_Data_Asset_DestroyMultiple(assets2, assetsCount); + OH_Data_Asset_DestroyOne(asset1); + OH_Data_Asset_DestroyOne(asset2); + valueBucket->destroy(valueBucket); } -void RdbNativeCursorTest::TearDown(void) +void RdbNativeCursorTest::SetAsset(Data_Asset *asset, int index) { + std::string indexString = std::to_string(index); + std::string name; + name.append("name").append(indexString); + int errcode = OH_Data_Asset_SetName(asset, name.c_str()); + EXPECT_EQ(errcode, RDB_OK); + std::string uri; + uri.append("uri").append(indexString); + errcode = OH_Data_Asset_SetUri(asset, uri.c_str()); + EXPECT_EQ(errcode, RDB_OK); + std::string path; + path.append("path").append(indexString); + errcode = OH_Data_Asset_SetPath(asset, path.c_str()); + EXPECT_EQ(errcode, RDB_OK); + errcode = OH_Data_Asset_SetCreateTime(asset, index); + EXPECT_EQ(errcode, RDB_OK); + errcode = OH_Data_Asset_SetModifyTime(asset, index); + EXPECT_EQ(errcode, RDB_OK); + errcode = OH_Data_Asset_SetSize(asset, index); + EXPECT_EQ(errcode, RDB_OK); + errcode = OH_Data_Asset_SetStatus(asset, Data_AssetStatus::ASSET_NORMAL); + EXPECT_EQ(errcode, RDB_OK); } /** @@ -239,7 +306,7 @@ HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_004, TestSize.Level1) { OH_Predicates *predicates = OH_Rdb_CreatePredicates("test"); - const char *columnNames[] = {"data1", "data2", "data3", "data4"}; + const char *columnNames[] = { "data1", "data2", "data3", "data4" }; int len = sizeof(columnNames) / sizeof(columnNames[0]); OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, columnNames, len); EXPECT_NE(cursor, NULL); @@ -304,7 +371,7 @@ HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_005, TestSize.Level1) { OH_Predicates *predicates = OH_Rdb_CreatePredicates("test"); - const char *columnNames[] = {"data1", "data2", "data3", "data4"}; + const char *columnNames[] = { "data1", "data2", "data3", "data4" }; int len = sizeof(columnNames) / sizeof(columnNames[0]); OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, columnNames, len); EXPECT_NE(cursor, NULL); @@ -369,4 +436,162 @@ HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_005, TestSize.Level1) predicates->destroy(predicates); cursor->destroy(cursor); -} \ No newline at end of file +} + +/** + * @tc.name: RDB_Native_cursor_test_005 + * @tc.desc: Normal testCase of cursor for anomalous branch. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_006, TestSize.Level1) +{ + int errCode = 0; + OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table"); + + OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0); + EXPECT_NE(cursor, NULL); + cursor->goToNextRow(cursor); + + OH_ColumnType type; + errCode = cursor->getColumnType(cursor, 0, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_INT64); + + errCode = cursor->getColumnType(cursor, 1, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_ASSET); + + errCode = cursor->getColumnType(cursor, 2, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_ASSETS); + + predicates->destroy(predicates); + cursor->destroy(cursor); +} + +/** + * @tc.name: RDB_Native_cursor_test_005 + * @tc.desc: Normal testCase of cursor for anomalous branch. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_007, TestSize.Level1) +{ + int errCode = 0; + OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table"); + + OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0); + EXPECT_NE(cursor, NULL); + cursor->goToNextRow(cursor); + + OH_ColumnType type; + errCode = cursor->getColumnType(cursor, 0, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_INT64); + int64_t id; + errCode = cursor->getInt64(cursor, 0, &id); + EXPECT_EQ(id, 1); + + errCode = cursor->getColumnType(cursor, 1, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_ASSET); + Data_Asset *asset = OH_Data_Asset_CreateOne(); + errCode = cursor->getAsset(cursor, 1, asset); + EXPECT_NE(asset, nullptr); + char name[10] = ""; + size_t nameLength = 10; + errCode = OH_Data_Asset_GetName(asset, name, &nameLength); + EXPECT_EQ(strcmp(name, "name1"), 0); + + char uri[10] = ""; + size_t uriLength = 10; + errCode = OH_Data_Asset_GetUri(asset, uri, &uriLength); + EXPECT_EQ(strcmp(uri, "uri1"), 0); + + char path[10] = ""; + size_t pathLength = 10; + errCode = OH_Data_Asset_GetPath(asset, path, &pathLength); + EXPECT_EQ(strcmp(path, "path1"), 0); + + int64_t createTime = 0; + errCode = OH_Data_Asset_GetCreateTime(asset, &createTime); + EXPECT_EQ(createTime, 1); + + int64_t modifyTime = 0; + errCode = OH_Data_Asset_GetModifyTime(asset, &modifyTime); + EXPECT_EQ(modifyTime, 1); + + size_t size = 0; + errCode = OH_Data_Asset_GetSize(asset, &size); + EXPECT_EQ(size, 1); + + Data_AssetStatus status = Data_AssetStatus::ASSET_NULL; + errCode = OH_Data_Asset_GetStatus(asset, &status); + EXPECT_EQ(status, ASSET_INSERT); + + predicates->destroy(predicates); + OH_Data_Asset_DestroyOne(asset); + cursor->destroy(cursor); +} + +/** + * @tc.name: RDB_Native_cursor_test_008 + * @tc.desc: Normal testCase of cursor for getAssets. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeCursorTest, RDB_Native_cursor_test_008, TestSize.Level1) +{ + int errCode = 0; + OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table"); + + OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0); + EXPECT_NE(cursor, NULL); + cursor->goToNextRow(cursor); + + OH_ColumnType type; + errCode = cursor->getColumnType(cursor, 0, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_INT64); + int64_t id; + errCode = cursor->getInt64(cursor, 0, &id); + EXPECT_EQ(id, 1); + + errCode = cursor->getColumnType(cursor, 2, &type); + EXPECT_EQ(type, OH_ColumnType::TYPE_ASSETS); + uint32_t assetCount = 0; + errCode = cursor->getAssets(cursor, 2, nullptr, &assetCount); + EXPECT_EQ(assetCount, 2); + Data_Asset **assets = OH_Data_Asset_CreateMultiple(assetCount); + errCode = cursor->getAssets(cursor, 2, assets, &assetCount); + EXPECT_EQ(assetCount, 2); + Data_Asset *asset = assets[1]; + EXPECT_NE(asset, NULL); + + char name[10] = ""; + size_t nameLength = 10; + errCode = OH_Data_Asset_GetName(asset, name, &nameLength); + EXPECT_EQ(strcmp(name, "name2"), 0); + + char uri[10] = ""; + size_t uriLength = 10; + errCode = OH_Data_Asset_GetUri(asset, uri, &uriLength); + EXPECT_EQ(strcmp(uri, "uri2"), 0); + + char path[10] = ""; + size_t pathLength = 10; + errCode = OH_Data_Asset_GetPath(asset, path, &pathLength); + EXPECT_EQ(strcmp(path, "path2"), 0); + + int64_t createTime = 0; + errCode = OH_Data_Asset_GetCreateTime(asset, &createTime); + EXPECT_EQ(createTime, 2); + + int64_t modifyTime = 0; + errCode = OH_Data_Asset_GetModifyTime(asset, &modifyTime); + EXPECT_EQ(modifyTime, 2); + + size_t size = 0; + errCode = OH_Data_Asset_GetSize(asset, &size); + EXPECT_EQ(size, 2); + + Data_AssetStatus status = Data_AssetStatus::ASSET_NULL; + errCode = OH_Data_Asset_GetStatus(asset, &status); + EXPECT_EQ(status, ASSET_INSERT); + + predicates->destroy(predicates); + OH_Data_Asset_DestroyMultiple(assets, assetCount); + cursor->destroy(cursor); +} diff --git a/relational_store/test/ndk/unittest/rdb_predicates_test.cpp b/relational_store/test/ndk/unittest/rdb_predicates_test.cpp index 289e1ec3a6042afcbde2b8db39b41ebf5b7f7249..2ae34ab7a45851dc489a9cd9336dc362103609c6 100644 --- a/relational_store/test/ndk/unittest/rdb_predicates_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_predicates_test.cpp @@ -95,6 +95,9 @@ void RdbNativePredicatesTest::SetUpTestCase(void) void RdbNativePredicatesTest::TearDownTestCase(void) { + char dropTableSql[] = "DROP TABLE IF EXISTS test"; + int errCode = OH_Rdb_Execute(predicatesTestRdbStore_, dropTableSql); + EXPECT_EQ(errCode, 0); delete predicatesTestRdbStore_; predicatesTestRdbStore_ = NULL; OH_Rdb_DeleteStore(&config_); diff --git a/relational_store/test/ndk/unittest/rdb_store_test.cpp b/relational_store/test/ndk/unittest/rdb_store_test.cpp index c584efc8e3b7c34300dd14cb6cea0b16eed9f54b..91285ba3ce69f2c9d92be643cd4c539f29f86eb1 100644 --- a/relational_store/test/ndk/unittest/rdb_store_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_store_test.cpp @@ -12,18 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include - #include #include #include + +#include "accesstoken_kit.h" #include "common.h" +#include "rdb_errno.h" #include "relational_store.h" #include "relational_store_error_code.h" +#include "token_setproc.h" using namespace testing::ext; using namespace OHOS::NativeRdb; +using namespace OHOS::Security::AccessToken; class RdbNativeStoreTest : public testing::Test { public: @@ -35,19 +38,49 @@ public: { config_.dataBaseDir = RDB_TEST_PATH; config_.storeName = "rdb_store_test.db"; - config_.bundleName = ""; + config_.bundleName = "com.example.distributed"; config_.moduleName = ""; config_.securityLevel = OH_Rdb_SecurityLevel::S1; config_.isEncrypt = false; config_.selfSize = sizeof(OH_Rdb_Config); + config_.area = RDB_SECURITY_AREA_EL1; } static OH_Rdb_Config config_; + static void MockHap(void); }; OH_Rdb_Store *storeTestRdbStore_; -OH_Rdb_Config RdbNativeStoreTest::config_ = {0}; +OH_Rdb_Config RdbNativeStoreTest::config_ = { 0 }; + +void RdbNativeStoreTest::MockHap(void) +{ + HapInfoParams info = { .userID = 100, + .bundleName = "com.example.distributed", + .instIndex = 0, + .appIDDesc = "com.example.distributed" }; + PermissionDef infoManagerTestPermDef = { .permissionName = "ohos.permission.test", + .bundleName = "com.example.distributed", + .grantMode = 1, + .availableLevel = APL_NORMAL, + .label = "label", + .labelId = 1, + .description = "open the door", + .descriptionId = 1 }; + PermissionStateFull infoManagerTestState = { .permissionName = "ohos.permission.test", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } }; + HapPolicyParams policy = { .apl = APL_NORMAL, + .domain = "test.domain", + .permList = { infoManagerTestPermDef }, + .permStateList = { infoManagerTestState } }; + AccessTokenKit::AllocHapToken(info, policy); +} + void RdbNativeStoreTest::SetUpTestCase(void) { + MockHap(); InitRdbConfig(); mkdir(config_.dataBaseDir, 0770); int errCode = 0; @@ -65,7 +98,7 @@ void RdbNativeStoreTest::TearDownTestCase(void) void RdbNativeStoreTest::SetUp(void) { - char createTableSql[] = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, " + char createTableSql[] = "CREATE TABLE store_test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, " "data3 FLOAT, data4 BLOB, data5 TEXT);"; int errCode = OH_Rdb_Execute(storeTestRdbStore_, createTableSql); EXPECT_EQ(errCode, 0); @@ -73,11 +106,21 @@ void RdbNativeStoreTest::SetUp(void) void RdbNativeStoreTest::TearDown(void) { - char dropTableSql[] = "DROP TABLE IF EXISTS test"; + char dropTableSql[] = "DROP TABLE IF EXISTS store_test"; int errCode = OH_Rdb_Execute(storeTestRdbStore_, dropTableSql); EXPECT_EQ(errCode, 0); } +void CloudSyncCallback(Rdb_ProgressDetails *progressDetails) +{ + EXPECT_NE(progressDetails, nullptr); + EXPECT_EQ(progressDetails->version, DISTRIBUTED_PROGRESS_DETAIL_VERSION); + EXPECT_EQ(progressDetails->schedule, Rdb_Progress::RDB_SYNC_FINISH); + EXPECT_EQ(progressDetails->code, Rdb_ProgressCode::RDB_CLOUD_DISABLED); + EXPECT_EQ(progressDetails->tableLength, 0); + Rdb_TableDetails *tableDetails = OH_Rdb_GetTableDetails(progressDetails, DISTRIBUTED_PROGRESS_DETAIL_VERSION); + EXPECT_NE(tableDetails, nullptr); +} /** * @tc.name: RDB_Native_store_test_001 * @tc.desc: Normal testCase of store for Insert、Update、Query. @@ -86,16 +129,16 @@ void RdbNativeStoreTest::TearDown(void) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_001, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -104,7 +147,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_001, TestSize.Level1) valueBucket->putReal(valueBucket, "data3", 200.1); valueBucket->putNull(valueBucket, "data5"); - OH_Predicates *predicates = OH_Rdb_CreatePredicates("test"); + OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test"); OH_VObject *valueObject = OH_Rdb_CreateValueObject(); const char *data1Value = "zhangSan"; valueObject->putText(valueObject, data1Value); @@ -161,16 +204,16 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_001, TestSize.Level1) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_002, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -179,10 +222,10 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_002, TestSize.Level1) valueBucket->putInt64(valueBucket, "data2", 13800); valueBucket->putReal(valueBucket, "data3", 200.1); valueBucket->putText(valueBucket, "data5", "ABCDEFGH"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 2); - OH_Predicates *predicates = OH_Rdb_CreatePredicates("test"); + OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test"); OH_VObject *valueObject = OH_Rdb_CreateValueObject(); const char *data1Value = "zhangSan"; valueObject->putText(valueObject, data1Value); @@ -190,7 +233,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_002, TestSize.Level1) errCode = OH_Rdb_Delete(storeTestRdbStore_, predicates); EXPECT_EQ(errCode, 1); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -239,16 +282,16 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_003, TestSize.Level1) OH_Rdb_BeginTransaction(storeTestRdbStore_); int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -257,12 +300,12 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_003, TestSize.Level1) valueBucket->putInt64(valueBucket, "data2", 13800); valueBucket->putReal(valueBucket, "data3", 200.1); valueBucket->putText(valueBucket, "data5", "ABCDEFGH"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 2); OH_Rdb_Commit(storeTestRdbStore_); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -283,16 +326,16 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_004, TestSize.Level1) OH_Rdb_BeginTransaction(storeTestRdbStore_); int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -301,12 +344,12 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_004, TestSize.Level1) valueBucket->putInt64(valueBucket, "data2", 13800); valueBucket->putReal(valueBucket, "data3", 200.1); valueBucket->putText(valueBucket, "data5", "ABCDEFGH"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 2); OH_Rdb_RollBack(storeTestRdbStore_); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -325,18 +368,18 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_004, TestSize.Level1) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_005, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -348,20 +391,20 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_005, TestSize.Level1) errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath1.c_str()); EXPECT_EQ(errCode, 0); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 2); - std::string backupPath2 = RDB_TEST_PATH + std::string("b.db"); + std::string backupPath2 = RDB_TEST_PATH + std::string("b.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath2.c_str()); EXPECT_EQ(errCode, 0); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 3); - std::string backupPath3 = RDB_TEST_PATH + std::string("c.db"); + std::string backupPath3 = RDB_TEST_PATH + std::string("c.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath3.c_str()); EXPECT_EQ(errCode, 0); // Continuous backup - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 4); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath3.c_str()); EXPECT_EQ(errCode, 0); @@ -406,18 +449,18 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_005, TestSize.Level1) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_006, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -439,7 +482,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_006, TestSize.Level1) errCode = OH_Rdb_Restore(storeTestRdbStore_, restorePath.c_str()); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_FILE_PATH); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 2); backupPath = " "; errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath.c_str()); @@ -498,16 +541,16 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_007, TestSize.Level1) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_008, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -529,7 +572,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_008, TestSize.Level1) errCode = OH_Rdb_Insert(storeTestRdbStore_, table, valueBucket); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - char querySql[] = "SELECT * FROM test"; + char querySql[] = "SELECT * FROM store_test"; OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); int rowCount = 0; @@ -548,16 +591,16 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_008, TestSize.Level1) HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_009, TestSize.Level1) { int errCode = 0; - OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); valueBucket->putInt64(valueBucket, "id", 1); valueBucket->putText(valueBucket, "data1", "zhangSan"); valueBucket->putInt64(valueBucket, "data2", 12800); valueBucket->putReal(valueBucket, "data3", 100.1); - uint8_t arr[] = {1, 2, 3, 4, 5}; + uint8_t arr[] = { 1, 2, 3, 4, 5 }; int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); valueBucket->clear(valueBucket); @@ -580,7 +623,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_009, TestSize.Level1) errCode = OH_Rdb_Update(storeTestRdbStore_, valueBucket, predicates1); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - OH_Predicates *predicates2 = OH_Rdb_CreatePredicates("test"); + OH_Predicates *predicates2 = OH_Rdb_CreatePredicates("store_test"); OH_Cursor *cursor = OH_Rdb_Query(storeTestRdbStore_, predicates2, NULL, 0); EXPECT_NE(cursor, NULL); @@ -640,7 +683,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_010, TestSize.Level1) int len = sizeof(arr) / sizeof(arr[0]); valueBucket->putBlob(valueBucket, "data4", arr, len); valueBucket->putText(valueBucket, "data5", "ABCDEFG"); - errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); EXPECT_EQ(errCode, 1); char *querySql = NULL; @@ -676,110 +719,195 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_011, TestSize.Level1) /** * @tc.name: RDB_Native_store_test_012 - * @tc.desc: Normal testCase of store for anomalous branch. + * @tc.desc: Normal testCase of store for CloudSync. * @tc.type: FUNC */ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_012, TestSize.Level1) { - int errCode = 0; - OH_Rdb_Config config; - config.dataBaseDir = RDB_TEST_PATH; - config.storeName = "rdb_store_error.db"; - config.bundleName = nullptr; - config.moduleName = ""; - config.securityLevel = OH_Rdb_SecurityLevel::S1; - config.isEncrypt = false; - config.selfSize = 0; - - auto store = OH_Rdb_GetOrOpen(nullptr, &errCode); - EXPECT_EQ(store, nullptr); - store = OH_Rdb_GetOrOpen(&config, nullptr); - EXPECT_EQ(store, nullptr); - store = OH_Rdb_GetOrOpen(&config, &errCode); - EXPECT_EQ(store, nullptr); - - config.selfSize = sizeof(OH_Rdb_Config); - store = OH_Rdb_GetOrOpen(&config, &errCode); - EXPECT_NE(store, nullptr); - - char createTableSql[] = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, " - "data3 FLOAT, data4 BLOB, data5 TEXT);"; - errCode = OH_Rdb_Execute(nullptr, createTableSql); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Execute(store, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); + EXPECT_NE(storeTestRdbStore_, nullptr); + constexpr int TABLE_COUNT = 1; + const char *table[TABLE_COUNT]; + table[0] = "store_test"; + EXPECT_EQ(table[0], "store_test"); + Rdb_SyncCallback callback = CloudSyncCallback; + auto errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); + + errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_CLOUD_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); + + errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_NATIVE_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); + + errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_NATIVE_FIRST, table, TABLE_COUNT, nullptr); + EXPECT_EQ(errorCode, RDB_E_INVALID_ARGS); +} - OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); - errCode = OH_Rdb_Insert(nullptr, "test", valueBucket); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Insert(store, nullptr, valueBucket); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Insert(store, "test", nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); +/** + * @tc.name: RDB_Native_store_test_013 + * @tc.desc: Abnormal testCase of store for SetDistributedTables. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_013, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + Rdb_DistributedConfig config{ .version = 0, .isAutoSync = true }; + constexpr int TABLE_COUNT = 1; + const char *table[TABLE_COUNT]; + table[0] = "store_test"; + int errcode = OH_Rdb_SetDistributedTables(storeTestRdbStore_, table, TABLE_COUNT, + Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD, &config); + EXPECT_EQ(errcode, RDB_E_INVALID_ARGS); + config.version = DISTRIBUTED_CONFIG_VERSION; + errcode = + OH_Rdb_SetDistributedTables(nullptr, table, TABLE_COUNT, Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD, &config); + EXPECT_EQ(errcode, RDB_E_INVALID_ARGS); +} - OH_Predicates *predicates = OH_Rdb_CreatePredicates("test"); - errCode = OH_Rdb_Update(nullptr, valueBucket, predicates); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Update(store, nullptr, predicates); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Update(store, valueBucket, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); +/** + * @tc.name: RDB_Native_store_test_014 + * @tc.desc: Normal testCase of store for CloudSync. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_014, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + constexpr int TABLE_COUNT = 1; + const char *table[TABLE_COUNT]; + table[0] = "store_test"; + Rdb_SyncCallback callback = CloudSyncCallback; + auto errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); + + errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_CLOUD_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); + + errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_NATIVE_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_OK); +} - errCode = OH_Rdb_Delete(nullptr, predicates); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Delete(store, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); +/** + * @tc.name: RDB_Native_store_test_015 + * @tc.desc: Abnormal testCase of store for CloudSync. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_015, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + constexpr int TABLE_COUNT = 1; + const char *table[TABLE_COUNT]; + table[0] = "store_test"; + Rdb_SyncCallback callback = CloudSyncCallback; + auto errorCode = + OH_Rdb_CloudSync(storeTestRdbStore_, Rdb_SyncMode::RDB_SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, nullptr); + EXPECT_EQ(errorCode, RDB_E_INVALID_ARGS); + errorCode = OH_Rdb_CloudSync(nullptr, Rdb_SyncMode::RDB_SYNC_MODE_CLOUD_FIRST, table, TABLE_COUNT, &callback); + EXPECT_EQ(errorCode, RDB_E_INVALID_ARGS); +} - auto cursor = OH_Rdb_Query(nullptr, predicates, NULL, 0); - EXPECT_EQ(cursor, nullptr); - cursor = OH_Rdb_Query(store, nullptr, NULL, 0); - EXPECT_EQ(cursor, nullptr); +/** + * @tc.name: RDB_Native_store_test_016 + * @tc.desc: Normal testCase for GetModifyTime. + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_016, TestSize.Level1) +{ + char createLogTableSql[] = "CREATE TABLE if not exists naturalbase_rdb_aux_rdbstoreimpltest_integer_log " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, " + "data3 FLOAT, data4 BLOB, data5 BOOLEAN);"; + int errCode = OH_Rdb_Execute(storeTestRdbStore_, createLogTableSql); + EXPECT_EQ(errCode, RDB_OK); + OH_VBucket *bucket = OH_Rdb_CreateValuesBucket(); + bucket->putInt64(bucket, "data_key", 1); + bucket->putInt64(bucket, "timestamp", 1000000000); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "naturalbase_rdb_aux_rdbstoreimpltest_integer_log", bucket); + EXPECT_EQ(errCode, 1); - char querySql[] = "SELECT * FROM test"; - cursor = OH_Rdb_ExecuteQuery(nullptr, querySql); - EXPECT_EQ(cursor, nullptr); - cursor = OH_Rdb_ExecuteQuery(store, nullptr); - EXPECT_EQ(cursor, nullptr); + OH_VObject *values = OH_Rdb_CreateValueObject(); + int64_t keys[] = { 1 }; + values->putInt64(values, keys, 1); - errCode = OH_Rdb_BeginTransaction(nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_RollBack(nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Commit(nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); + OH_Cursor *cursor; + cursor = + OH_Rdb_FindModifyTime(storeTestRdbStore_, "rdbstoreimpltest_integer", "ROWID", values); + int rowCount; + errCode = cursor->getRowCount(cursor, &rowCount); + EXPECT_EQ(errCode, RDB_OK); + EXPECT_EQ(rowCount, 1); + cursor->goToNextRow(cursor); + int64_t key = 0; + cursor->getInt64(cursor, 0, &key); + EXPECT_EQ(key, 1); + int64_t time = 0; + cursor->getInt64(cursor, 1, &time); + EXPECT_EQ(time, 100000); - char backupDir[] = "backup.db"; - errCode = OH_Rdb_Backup(nullptr, backupDir); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Backup(store, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Restore(nullptr, backupDir); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_Restore(store, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); + cursor->destroy(cursor); + char dropLogTableSql[] = "DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log"; + errCode = OH_Rdb_Execute(storeTestRdbStore_, dropLogTableSql); + EXPECT_EQ(errCode, RDB_OK); +} - int version = 1; - errCode = OH_Rdb_SetVersion(nullptr, version); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_GetVersion(nullptr, &version); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_GetVersion(store, nullptr); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); +/** + * @tc.name: RDB_Native_store_test_017 + * @tc.desc: Abnormal testCase for GetModifyTime, tablename columnName, keys is empty, + * and resultSet is null or empty + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_017, TestSize.Level1) +{ + char createLogTableSql[] = "CREATE TABLE if not exists naturalbase_rdb_aux_rdbstoreimpltest_integer_log " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, data_key INTEGER, " + "data3 FLOAT, data4 BLOB, data5 BOOLEAN);"; + int errCode = OH_Rdb_Execute(storeTestRdbStore_, createLogTableSql); + EXPECT_EQ(errCode, RDB_OK); + OH_VBucket *bucket = OH_Rdb_CreateValuesBucket(); + bucket->putInt64(bucket, "data_key", 1); + bucket->putInt64(bucket, "timestamp", 1000000000); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "naturalbase_rdb_aux_rdbstoreimpltest_integer_log", bucket); + EXPECT_EQ(errCode, 1); - errCode = OH_Rdb_CloseStore(nullptr); + OH_VObject *values = OH_Rdb_CreateValueObject(); + int64_t keys[] = { 1 }; + values->putInt64(values, keys, 1); + + // table name is "" + OH_Cursor *cursor; + cursor = OH_Rdb_FindModifyTime(storeTestRdbStore_, "", "data_key", values); + int rowCount = 0; + errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - errCode = OH_Rdb_DeleteStore(nullptr); + + // table name is not exist , resultSet is null + cursor->destroy(cursor); + cursor = OH_Rdb_FindModifyTime(storeTestRdbStore_, "test", "data_key", values); + cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - config.dataBaseDir = nullptr; - errCode = OH_Rdb_DeleteStore(&config); + + // columnName is "" + cursor->destroy(cursor); + cursor = OH_Rdb_FindModifyTime(storeTestRdbStore_, "rdbstoreimpltest_integer", "", values); + cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - config.dataBaseDir = RDB_TEST_PATH; - config.storeName = nullptr; - errCode = OH_Rdb_DeleteStore(&config); + + // keys is empty + cursor->destroy(cursor); + OH_VObject *emptyValues = OH_Rdb_CreateValueObject(); + cursor = OH_Rdb_FindModifyTime(storeTestRdbStore_, "rdb_aux_rdbstoreimpltest_integer", "data_key", + emptyValues); + cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); - config.storeName = "rdb_store_error.db"; - OH_Rdb_CloseStore(store); - OH_Rdb_DeleteStore(&config); -} \ No newline at end of file + cursor->destroy(cursor); + char dropLogTableSql[] = "DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log"; + errCode = OH_Rdb_Execute(storeTestRdbStore_, dropLogTableSql); + EXPECT_EQ(errCode, RDB_OK); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 90f0958874012b6a90ec61c5a343a4430c0737d3..7be9e98ffee9b92c97be316d139d2c5d4bce0a30 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,6 +17,7 @@ set(KV_STORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../kv_store) include_directories(${MOCK_DIR}/src/) include_directories(${MOCK_DIR}/sqlite/include) include_directories(${KV_STORE_DIR}/frameworks/common) +include_directories(${KV_STORE_DIR}/interfaces/innerkits/distributeddata/include) include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) include_directories(${CMAKE_SOURCE_DIR}/googletest/googletest/include) include_directories(${CMAKE_SOURCE_DIR}/googletest/googlemock/include) @@ -94,9 +95,9 @@ target_include_directories(RDBTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../relati #************************************************PerferencesTest start************************************************# aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/test/native/unittest preferencesTestSrc) -add_executable(PerferencesTest ${preferencesTestSrc} ${mainSrc} ${clientSrc}) -target_link_libraries(PerferencesTest ${links} gtest_main gcov preferences kvdb) -target_include_directories(PerferencesTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/native/include) +add_executable(PerferencesTest ${preferencesTestSrc} ${mainSrc} ${serviceSrc}) +target_link_libraries(PerferencesTest gtest_main gcov preferences app) +target_include_directories(PerferencesTest PRIVATE BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/native/include) target_include_directories(PerferencesTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/common/include) target_include_directories(PerferencesTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/native/platform/include) #************************************************PerferencesTest end************************************************# @@ -104,7 +105,7 @@ target_include_directories(PerferencesTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/. #************************************************DataShareTest start************************************************# file(GLOB_RECURSE dataShareTestSrc ${CMAKE_CURRENT_SOURCE_DIR}/../data_share/test/native/unittest/*.cpp) add_executable(DataShareTest ${dataShareTestSrc} ${mainSrc} ${serviceSrc}) -target_link_libraries(DataShareTest ${links} gtest_main gcov data_share) +target_link_libraries(DataShareTest ${links} gtest_main gcov data_share service) target_include_directories(DataShareTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_share/frameworks/native/common/include) target_include_directories(DataShareTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_share/test/native/unittest/mediadatashare_test/include) target_include_directories(DataShareTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_share/frameworks/native/consumer/controller/common) diff --git a/test/include/CMakeLists.txt b/test/include/CMakeLists.txt index 491119afe55490d406722d0c5db6b7898b624704..fd0d4b2e1af7e36c2c8a563aed0f3ed5c34913f9 100644 --- a/test/include/CMakeLists.txt +++ b/test/include/CMakeLists.txt @@ -42,7 +42,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/dist include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/framework/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/app/src/) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/native/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/frameworks/js/napi/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../preferences/interfaces/inner_api/include) diff --git a/test/service/load_service.cpp b/test/service/load_service.cpp index 679bbc4bb77b83192abe5c95a517326438dede7a..7022eaaa6763d4b5481a45a23e565a2d8b29dc52 100644 --- a/test/service/load_service.cpp +++ b/test/service/load_service.cpp @@ -14,11 +14,11 @@ */ #include "../load_service.h" -#include "store_factory.h" +//#include "store_factory.h" #include "uninstaller/uninstaller.h" LoadService::LoadService() { - OHOS::DistributedKv::StoreFactory::GetInstance(); +// OHOS::DistributedKv::StoreFactory::GetInstance(); OHOS::DistributedKv::Uninstaller::GetInstance(); } LoadService::~LoadService() diff --git a/udmf/framework/common/preset_type_descriptors.cpp b/udmf/framework/common/preset_type_descriptors.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88994e0732131a2911e06c8b796cfdcf3c8e1f8d --- /dev/null +++ b/udmf/framework/common/preset_type_descriptors.cpp @@ -0,0 +1,660 @@ +/* + * 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 "preset_type_descriptors.h" +namespace OHOS { +namespace UDMF { +PresetTypeDescriptors::PresetTypeDescriptors() +{ + InitDescriptors(); +} + +PresetTypeDescriptors::~PresetTypeDescriptors() +{ +} + +PresetTypeDescriptors &PresetTypeDescriptors::GetInstance() +{ + static auto instance_ = new PresetTypeDescriptors(); + return *instance_; +} + +std::vector &PresetTypeDescriptors::GetTypeDescriptors() +{ + return typeDescriptors_; +} + +void PresetTypeDescriptors::InitDescriptors() +{ + typeDescriptors_ = { + {"general.database", + {}, + {}, + {}, + "Base type for databases.", + "", + ""}, + {"general.message", + {}, + {}, + {}, + "Base type for messages (email, IM, and so on).", + "", + ""}, + {"general.contact", + {}, + {}, + {}, + "Base type for contact information.", + "", + ""}, + {"general.archive", + {}, + {}, + {}, + "Base type for an archive of files and directories.", + "", + ""}, + {"general.disk-image", + {"general.archive"}, + {}, + {}, + "Base type for items mountable as a volume.", + "", + ""}, + {"general.text", + {}, + {}, + {}, + "Base type for all text, including text with markup information (HTML, RTF, and so on).", + "", + ""}, + {"general.plain-text", + {"general.text"}, + {".txt"}, + {"text/plain"}, + "Text of unspecified encoding, with no markup. Equivalent to the MIME type text/plain", + "", + ""}, + {"general.html", + {"general.text"}, + {".html", ".htm"}, + {"text/html"}, + "HTML text.", + "", + ""}, + {"general.xml", + {"general.text"}, + {".xml"}, + {"text/xml"}, + "XML text.", + "", + ""}, + {"general.source-code", + {"general.plain-text"}, + {}, + {}, + "Generic source code.", + "", + ""}, + {"general.c-source", + {"general.source-code"}, + {".c"}, + {}, + "C source code.", + "", + ""}, + {"general.c-plus-plus-source", + {"general.source-code"}, + {".cp", ".cpp", ".c++", ".cc", ".cxx"}, + {}, + "C++ source code.", + "", + ""}, + {"general.c-header", + {"general.source-code"}, + {".h"}, + {}, + "C header file.", + "", + ""}, + {"general.c-plus-plus-header", + {"general.source-code"}, + {".hpp", ".h++", ".hxx"}, + {}, + "C++ header file.", + "", + ""}, + {"general.script", + {"general.source-code"}, + {}, + {}, + "Base type for scripting language source code.", + "", + ""}, + {"general.shell-script", + {"general.script"}, + {".sh", ".command"}, + {}, + "Shell script.", + "", + ""}, + {"general.csh-script", + {"general.shell-script"}, + {".csh"}, + {}, + "C-shell script.", + "", + ""}, + {"general.perl-script", + {"general.shell-script"}, + {".pl", ".pm"}, + {"text/x-perl-script"}, + "Perl script.", + "", + ""}, + {"general.python-script", + {"general.shell-script"}, + {".py"}, + {"text/x-python-script"}, + "Python script.", + "", + ""}, + {"general.ruby-script", + {"general.shell-script"}, + {".rb", ".rbw"}, + {"text/ruby-script"}, + "Ruby script.", + "", + ""}, + {"general.php-script", + {"general.shell-script"}, + {".php", ".php3", ".php4", ".ph3", ".ph4", ".phtml"}, + {"text/x-php-script, text/php, application/php"}, + "PHP script.", + "", + ""}, + {"general.tar-archive", + {"general.archive"}, + {".tar"}, + {"application/x-tar, application/tar"}, + "Tar archive.", + "", + ""}, + {"general.vcard", + {}, + {}, + {}, + "Base type for electronic business card.", + "", + ""}, + {"general.image", + {"general.media"}, + {}, + {}, + "Base type for images.", + "", + ""}, + {"general.jpeg", + {"general.image"}, + {".jpg", ".jpeg"}, + {"image/jpeg"}, + "JPEG image.", + "", + ""}, + {"general.tiff", + {"general.image"}, + {".tif", ".tiff"}, + {"image/tiff"}, + "TIFF image.", + "", + ""}, + {"general.raw-image", + {"general.image"}, + {}, + {}, + "Base type for digital camera raw image formats.", + "", + ""}, + {"general.png", + {"general.image"}, + {".png"}, + {"image/png"}, + "PNG image", + "", + ""}, + {"general.video", + {"general.media"}, + {}, + {}, + "Base type for video.", + "", + ""}, + {"general.avi", + {"general.video"}, + {".avi", ".vfw"}, + {"video/avi", "video/msvideo", "video/x-msvideo"}, + "AVI video.", + "", + ""}, + {"general.mpeg", + {"general.video"}, + {".mpg", ".mpeg"}, + {"video/mpg", "video/mpeg", "video/x-mpg", "video/x-mpeg"}, + "MPEG-1 or MPEG-2 video.", + "", + ""}, + {"general.mpeg-4", + {"general.video"}, + {".mp4"}, + {"video/mp4", "video/mp4v"}, + "MPEG-4 video.", + "", + ""}, + {"general.3gpp", + {"general.video"}, + {".3gp", ".3gpp"}, + {"video/3gpp"}, + "3GPP video.", + "", + ""}, + {"general.3gpp2", + {"general.video"}, + {".3g2", ".3gp2"}, + {"video/3gpp2"}, + "3GPP2 video.", + "", + ""}, + {"general.audio", + {"general.media"}, + {}, + {}, + "Base type for audio.", + "", + ""}, + {"general.mp3", + {"general.audio"}, + {".mp3,"}, + {"audio/mp3"}, + "MPEG-3 audio.", + "", + ""}, + {"general.aac", + {"general.audio"}, + {".aac"}, + {"audio/aac"}, + "AAC audio.", + "", + ""}, + {"general.aiff", + {"general.audio"}, + {".aiff"}, + {"audio/aiff"}, + "AIFF audio.", + "", + ""}, + {"general.alac", + {"general.audio"}, + {".alac"}, + {"audio/alac"}, + "ALAC audio.", + "", + ""}, + {"general.bz2-archive", + {"general.archive"}, + {".bz2"}, + {"application/x-bzip2"}, + "BZip2 archive.", + "", + ""}, + {"general.calendar", + {}, + {}, + {}, + "Base type for scheduled events.", + "", + ""}, + {"general.ebook", + {}, + {}, + {}, + "Base type for ebook.", + "", + ""}, + {"general.epub", + {"general.ebook"}, + {".epub"}, + {"application/epub+zip"}, + "Electronic publication (EPUB) format.", + "", + ""}, + {"general.flac", + {"general.audio"}, + {".flac"}, + {"audio/flac"}, + "FLAC audio.", + "", + ""}, + {"general.java-script", + {"general.source-code"}, + {".js", ".jscript", ".javascript"}, + {"text/javascript"}, + "", + "", + ""}, + {"general.java-source", + {"general.source-code"}, + {".java", ".jav"}, + {}, + "Java source code.", + "", + ""}, + {"general.location", + {"general.navigation"}, + {}, + {}, + "Navigation location.", + "", + ""}, + {"general.media", + {}, + {}, + {}, + "Base type for media.", + "", + ""}, + {"general.navigation", + {}, + {}, + {}, + "Base type for navigation.", + "", + ""}, + {"general.ogg", + {"general.audio"}, + {".ogg"}, + {"audio/ogg"}, + "OGG audio.", + "", + ""}, + {"general.pcm", + {"general.audio"}, + {".pcm"}, + {"audio/pcm"}, + "PCM audio.", + "", + ""}, + {"general.type-script", + {"general.source-code"}, + {".ts"}, + {}, + "TypeScript source code.", + "", + ""}, + {"general.zip-archive", + {"general.archive"}, + {".zip"}, + {"application/zip"}, + "Zip archive.", + "", + ""}, + {"general.hyperlink", + {"general.text"}, + {}, + {}, + "Hyperlink.", + "", + ""}, + {"general.file", + {}, + {}, + {}, + "Base type for file.", + "", + ""}, + {"general.directory", + {}, + {}, + {}, + "Base type for directory.", + "", + ""}, + {"general.folder", + {}, + {}, + {}, + "Base type for folder.", + "", + ""}, + {"general.symlink", + {}, + {}, + {}, + "Base type for symlink.", + "", + ""}, + {"com.adobe.pdf", + {}, + {".pdf"}, + {"application/pdf"}, + "PDF data.", + "", + ""}, + {"com.adobe.postscript", + {}, + {".ps"}, + {"application/postscript"}, + "PostScript data.", + "", + ""}, + {"com.adobe.encapsulated-postscript", + {}, + {".eps"}, + {}, + "Encapsulated PostScript.", + "", + ""}, + {"com.adobe.photoshop-image", + {"general.image"}, + {".psd"}, + {"image/x-photoshop", "image/photoshop", "image/psd", "application/photoshop"}, + "Adobe Photoshop document.", + "", + ""}, + {"com.adobe.illustrator.ai-image", + {"general.image"}, + {".ai"}, + {}, + "Adobe Illustrator document.", + "", + ""}, + {"com.microsoft.bmp", + {"general.image"}, + {".bmp"}, + {}, + "Windows bitmap image.", + "", + ""}, + {"com.microsoft.ico", + {"general.image"}, + {".ico"}, + {}, + "Windows icon image.", + "", + ""}, + {"com.microsoft.word.doc", + {}, + {".doc"}, + {"application/msword"}, + "Microsoft Word data.", + "", + ""}, + {"com.microsoft.excel.xls", + {}, + {".xls"}, + {"application/vnd.ms-excel"}, + "Microsoft Excel data.", + "", + ""}, + {"com.microsoft.powerpoint.ppt", + {}, + {".ppt"}, + {"application/mspowerpoint"}, + "Microsoft PowerPoint presentation.", + "", + ""}, + {"com.microsoft.waveform-audio", + {"general.audio"}, + {".wav", ".wave", ".WAV"}, + {"audio/wav", "audio/wave"}, + "Waveform audio.", + "", + ""}, + {"com.microsoft.windows-media-wm", + {"general.video"}, + {".wm"}, + {"video/x-ms-wm"}, + "Windows WM video.", + "", + ""}, + {"com.microsoft.windows-media-wmv", + {"general.video"}, + {".wmv"}, + {"video/x-ms-wmv"}, + "Windows WMV video.", + "", + ""}, + {"com.microsoft.windows-media-wmp", + {"general.video"}, + {".wmp"}, + {"video/x-ms-wmp"}, + "Windows WMP video.", + "", + ""}, + {"com.microsoft.windows-media-wma", + {"general.audio"}, + {".wma"}, + {"video/x-ms-wma"}, + "Windows WMA audio.", + "", + ""}, + {"com.microsoft.windows-media-wmx", + {"general.audio"}, + {".wmx"}, + {"video/x-ms-wmx"}, + "Windows WMX audio.", + "", + ""}, + {"com.microsoft.windows-media-wvx", + {"general.audio"}, + {".wvx"}, + {"video/x-ms-wvx"}, + "Windows WVX audio.", + "", + ""}, + {"com.microsoft.windows-media-wax", + {"general.audio"}, + {".wax"}, + {"video/x-ms-wax"}, + "Windows WAX audio.", + "", + ""}, + {"com.amazon.azw", + {"general.ebook"}, + {".azw"}, + {"application/vnd.amazon.ebook"}, + "AZW ebook.", + "", + ""}, + {"com.amazon.azw3", + {"general.ebook"}, + {".azw3"}, + {"application/vnd.amazon.mobi8-ebook", "application/x-mobi8-ebook"}, + "AZW3 ebook.", + "", + ""}, + {"com.amazon.kfx", + {"general.ebook"}, + {".kfx"}, + {}, + "KFX ebook.", + "", + ""}, + {"com.amazon.mobi", + {"general.ebook"}, + {".mobi"}, + {"application/x-mobipocket-ebook"}, + "MOBI ebook.", + "", + ""}, + {"com.sun.java-archive", + {"general.archive"}, + {".jar"}, + {"application/java-archive"}, + "Java archive.", + "", + ""}, + {"org.gnu.gnu-tar-archive", + {"general.archive"}, + {".gtar"}, + {"application/x-gtar"}, + "GNU archive.", + "", + ""}, + {"org.gnu.gnu-zip-archive", + {"general.archive"}, + {".gz", ".gzip"}, + {"application/x-gzip", "application/gzip"}, + "Gzip archive.", + "", + ""}, + {"org.gnu.gnu-zip-tar-archive", + {"general.archive"}, + {".tgz"}, + {}, + "Gzip tar archive.", + "", + ""}, + {"openharmony.form", + {}, + {}, + {}, + "OpenHarmony system defined form.", + "", + ""}, + {"openharmony.app-item", + {}, + {}, + {}, + "OpenHarmony system defined app item.", + "", + ""}, + {"openharmony.pixel-map", + {}, + {}, + {}, + "OpenHarmony system defined pixel map.", + "", + ""}, + {"openharmony.atomic-service", + {}, + {}, + {}, + "OpenHarmony system defined atomic service.", + "", + ""} + }; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/common/preset_type_descriptors.h b/udmf/framework/common/preset_type_descriptors.h new file mode 100644 index 0000000000000000000000000000000000000000..c2661964596de66e4c8296e9f3fd96c3f7047683 --- /dev/null +++ b/udmf/framework/common/preset_type_descriptors.h @@ -0,0 +1,37 @@ +/* + * 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 UDMF_PRESET_TYPE_DESCRIPTORS +#define UDMF_PRESET_TYPE_DESCRIPTORS +#include "type_descriptor.h" +#include "error_code.h" + +namespace OHOS { +namespace UDMF { +class PresetTypeDescriptors { +public: + static PresetTypeDescriptors &GetInstance(); + std::vector &GetTypeDescriptors(); +private: + PresetTypeDescriptors(); + ~PresetTypeDescriptors(); + PresetTypeDescriptors(const PresetTypeDescriptors &obj) = delete; + PresetTypeDescriptors &operator=(const PresetTypeDescriptors &obj) = delete; + + void InitDescriptors(); + std::vector typeDescriptors_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_PRESET_TYPE_DESCRIPTORS \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/client/utd_client.cpp b/udmf/framework/innerkitsimpl/client/utd_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6e09cc11c4fb0938cbac3014b18fd7cb2db9e40 --- /dev/null +++ b/udmf/framework/innerkitsimpl/client/utd_client.cpp @@ -0,0 +1,50 @@ +/* + * 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 "utd_client.h" +#include "logger.h" +#include "preset_type_descriptors.h" + +namespace OHOS { +namespace UDMF { +UtdClient::UtdClient() +{ + LOG_INFO(UDMF_CLIENT, "construct UtdClient sucess."); +} + +UtdClient::~UtdClient() +{ +} + +UtdClient &UtdClient::GetInstance() +{ + static auto instance_ = new UtdClient(); + return *instance_; +} + +Status UtdClient::GetTypeDescriptor(const std::string &typeId, std::shared_ptr &descriptor) +{ + descriptors_ = PresetTypeDescriptors::GetInstance().GetTypeDescriptors(); + for (const auto &utdType : descriptors_) { + if (utdType.GetTypeId() == typeId) { + descriptor = std::make_shared(utdType); + LOG_DEBUG(UDMF_CLIENT, "get descriptor success. %{public}s ", typeId.c_str()); + } + } + + return Status::E_OK; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/consumer/controller/provider/include/general_controller_porvider_impl.h b/udmf/framework/innerkitsimpl/data/type_descriptor.cpp similarity index 30% rename from data_share/frameworks/native/consumer/controller/provider/include/general_controller_porvider_impl.h rename to udmf/framework/innerkitsimpl/data/type_descriptor.cpp index 1f75d74ce09037eb87a8199879b6ec5e19506348..d014e8889df034884f75aa9a8d548ad125c376ab 100644 --- a/data_share/frameworks/native/consumer/controller/provider/include/general_controller_porvider_impl.h +++ b/udmf/framework/innerkitsimpl/data/type_descriptor.cpp @@ -13,44 +13,62 @@ * limitations under the License. */ -#ifndef GENERAL_CONTROLLER_PORVIDER_IMPL_H -#define GENERAL_CONTROLLER_PORVIDER_IMPL_H +#include "type_descriptor.h" -#include "datashare_connection.h" -#include "general_controller.h" +#include "logger.h" namespace OHOS { -namespace AAFwk { -class IDataAbilityObserver; +namespace UDMF { +TypeDescriptor::TypeDescriptor(const std::string &typeId, const std::set &belongingToTypes, + const std::vector &filenameExtensions, const std::vector &mimeTypes, + const std::string &description, const std::string &referenceURL, const std::string &iconFile) : typeId_(typeId), + belongingToTypes_(belongingToTypes), filenameExtensions_(filenameExtensions), mimeTypes_(mimeTypes), + description_(description), referenceURL_(referenceURL), iconFile_(iconFile) +{ } -namespace DataShare { -class GeneralControllerProviderImpl : public GeneralController { -public: - GeneralControllerProviderImpl(std::shared_ptr connection, - const Uri &uri, const sptr &token); +TypeDescriptor::~TypeDescriptor() +{ +} - virtual ~GeneralControllerProviderImpl() = default; +bool TypeDescriptor::Equals(std::shared_ptr descriptor) +{ + return descriptor->GetTypeId() == this->GetTypeId(); +} - int Insert(const Uri &uri, const DataShareValuesBucket &value) override; +const std::string& TypeDescriptor::GetTypeId() const +{ + return typeId_; +} - int Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; +std::set TypeDescriptor::GetBelongingToTypes() +{ + return belongingToTypes_; +} - int Delete(const Uri &uri, const DataSharePredicates &predicates) override; +std::string TypeDescriptor::GetIconFile() +{ + return iconFile_; +} - std::shared_ptr Query(const Uri &uri, const DataSharePredicates &predicates, - std::vector &columns, DatashareBusinessError &businessError) override; +std::string TypeDescriptor::GetDescription() +{ + return description_; +} - void RegisterObserver(const Uri &uri, const sptr &dataObserver) override; +std::string TypeDescriptor::GetReferenceURL() +{ + return referenceURL_; +} - void UnregisterObserver(const Uri &uri, const sptr &dataObserver) override; +std::vector TypeDescriptor::GetFilenameExtensions() +{ + return filenameExtensions_; +} - void NotifyChange(const Uri &uri) override; -private: - std::shared_ptr connection_ = nullptr; - sptr token_ = {}; - Uri uri_ = Uri(""); -}; -} // namespace DataShare -} // namespace OHOS -#endif // GENERAL_CONTROLLER_PORVIDER_IMPL_H +std::vector TypeDescriptor::GetMimeTypes() +{ + return mimeTypes_; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/data/unified_data.cpp b/udmf/framework/innerkitsimpl/data/unified_data.cpp index 497a492a53c0fb913a855be894172f7a7e646486..f40332b1ec07fdf79b4cbf006a143395cdcf64a2 100644 --- a/udmf/framework/innerkitsimpl/data/unified_data.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_data.cpp @@ -15,6 +15,8 @@ #include "unified_data.h" +#include "logger.h" + namespace OHOS { namespace UDMF { int64_t UnifiedData::GetSize() @@ -89,5 +91,39 @@ bool UnifiedData::IsEmpty() const { return records_.empty(); } + +bool UnifiedData::IsValid() +{ + if (this->IsEmpty()) { + LOG_ERROR(UDMF_FRAMEWORK, "Empty data without any record!"); + return false; + } + if (this->GetSize() > MAX_DATA_SIZE) { + LOG_ERROR(UDMF_FRAMEWORK, "Exceeded data limit!"); + return false; + } + for (const auto &record : this->GetRecords()) { + if (record->GetSize() > UnifiedRecord::MAX_RECORD_SIZE) { + LOG_ERROR(UDMF_FRAMEWORK, "Exceeded record limit!"); + return false; + } + } + return true; +} + +bool UnifiedData::IsComplete() +{ + std::shared_ptr runtime = this->GetRuntime(); + if (runtime == nullptr) { + return false; + } + if (static_cast(this->GetRecords().size()) != runtime->recordTotalNum) { + LOG_ERROR(UDMF_FRAMEWORK, + "The records of unifiedData is incomplete, expected recordsNum is %{public}u, not %{public}zu.", + runtime->recordTotalNum, this->GetRecords().size()); + return false; + } + return true; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp index 4698c3ea4f6fcfa5a63b35d8e9e7b058c0ee6b41..3dd0f5eeefef3409b37ebabde0bb4e92a12a10f0 100644 --- a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp +++ b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp @@ -368,6 +368,22 @@ napi_status NapiDataUtils::SetValue(napi_env env, const UDDetails &in, napi_valu return napi_ok; } +napi_status NapiDataUtils::GetValue(napi_env env, napi_value in, std::shared_ptr &descriptor) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "napi_value -> std::GetValue TypeDescriptor"); + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + LOG_ERROR_RETURN((status == napi_ok) && (type == napi_object), "invalid type", napi_invalid_arg); + TypeDescriptorNapi *descriptorNapi = nullptr; + napi_unwrap(env, in, reinterpret_cast(&descriptorNapi)); + LOG_ERROR_RETURN((descriptorNapi != nullptr), "invalid type", napi_invalid_arg); + descriptor = descriptorNapi->value_; + if (descriptor == nullptr) { + LOG_DEBUG(UDMF_KITS_NAPI, "napi_value -> GetValue TypeDescriptor failed "); + } + return napi_ok; +} + bool NapiDataUtils::IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType) { napi_valuetype valueType = napi_undefined; diff --git a/udmf/framework/jskitsimpl/data/application_defined_record_napi.cpp b/udmf/framework/jskitsimpl/data/application_defined_record_napi.cpp index bf52d0963c3351239cfe03ff854d7fec573e8a1c..2bc52b2b0bad4c49932f1956925a174f1de081f7 100644 --- a/udmf/framework/jskitsimpl/data/application_defined_record_napi.cpp +++ b/udmf/framework/jskitsimpl/data/application_defined_record_napi.cpp @@ -45,7 +45,7 @@ napi_value ApplicationDefinedRecordNapi::New(napi_env env, napi_callback_info in ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_INVALID_PARAMETERS, "invalid arguments!"); auto *record = new (std::nothrow) ApplicationDefinedRecordNapi(); - ASSERT_ERR(ctxt->env, record != nullptr, Status::E_UNKNOWN, "no memory for application defined record!"); + ASSERT_ERR(ctxt->env, record != nullptr, Status::E_ERROR, "no memory for application defined record!"); record->value_ = std::make_shared(); ASSERT_CALL(ctxt->env, napi_wrap(env, ctxt->self, record, Destructor, nullptr, nullptr), record); return ctxt->self; @@ -56,7 +56,7 @@ void ApplicationDefinedRecordNapi::NewInstance(napi_env env, std::shared_ptrvalue_ = std::static_pointer_cast(in); ASSERT_CALL_DELETE(env, napi_wrap(env, out, record, Destructor, nullptr, nullptr), record); } diff --git a/udmf/framework/jskitsimpl/data/audio_napi.cpp b/udmf/framework/jskitsimpl/data/audio_napi.cpp index bc85616833072253769c5d8d6e35daa868d754a5..14d15f63c843a6ea48d74cd2aeb110d28e570723 100644 --- a/udmf/framework/jskitsimpl/data/audio_napi.cpp +++ b/udmf/framework/jskitsimpl/data/audio_napi.cpp @@ -48,7 +48,7 @@ napi_value AudioNapi::New(napi_env env, napi_callback_info info) ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_INVALID_PARAMETERS, "invalid arguments!"); auto *audio = new (std::nothrow) AudioNapi(); - ASSERT_ERR(ctxt->env, audio != nullptr, Status::E_UNKNOWN, "no memory for audio!"); + ASSERT_ERR(ctxt->env, audio != nullptr, Status::E_ERROR, "no memory for audio!"); audio->value_ = std::make_shared