diff --git a/BUILD.gn b/BUILD.gn index 8c8a8314278b10bf36860556da7c0c3251338b51..f25102073259ae5ace6ff0d0de23f748d5e7d495 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -18,6 +18,7 @@ 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/bundle.json b/bundle.json index 79367b70bff8f40b30d7a9fb094d3a3e9cab4707..a5d2bd57f46cd728cf4daf6c2b3815ea71863c93 100644 --- a/bundle.json +++ b/bundle.json @@ -89,7 +89,8 @@ "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app:build_module", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:build_module", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:build_module", - "//foundation/distributeddatamgr/datamgr_service/conf:build_module" + "//foundation/distributeddatamgr/datamgr_service/conf:build_module", + "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd:build_module" ], "inner_kits": [], "test": [ diff --git a/conf/config.json b/conf/config.json index 91ca003bbdfef4b4bd57c1f761faafd67e6c6e49..6f13c2cfcfe47725217790225733da2c79e931f0 100644 --- a/conf/config.json +++ b/conf/config.json @@ -15,7 +15,11 @@ } }, { - "lib": "libconfigdemo2.z.so" + "description": "cloud data interface adapter", + "lib": "libdistributedclouddata.z.so" + }, + { + "lib": "libudmf_server.z.so" } ], "bundleChecker": { diff --git a/datamgr_service.gni b/datamgr_service.gni index d1abd9afc053bc647945c6168a748edab1c67005..6ec402a19d78db68d0e97b6f7d131cf7793fb8c7 100644 --- a/datamgr_service.gni +++ b/datamgr_service.gni @@ -11,6 +11,21 @@ # See the License for the specific language governing permissions and # limitations under the License. +distributedfilejs_path = "//foundation/distributeddatamgr/distributedfile" + +kv_store_path = "//foundation/distributeddatamgr/kv_store" + +kv_store_common_path = "${kv_store_path}/frameworks/common" + +kv_store_distributeddb_path = "${kv_store_path}/frameworks/libs/distributeddb" + +dsoftbus_core_path = "//foundation/communication/dsoftbus/core/common/include" + +datashare_path = "//foundation/distributeddatamgr/data_share" + +ipc_core_path = "//foundation/communication/ipc/interfaces/innerkits/ipc_core" + +device_manager_path = "//foundation/distributedhardware/device_manager" declare_args() { datamgr_service_power = true if (!defined(global_parts_info.power_manager_native_powermgr_client) || diff --git a/services/distributeddataservice/adapter/BUILD.gn b/services/distributeddataservice/adapter/BUILD.gn index 8f2232af1d99411ce4c7ab4a22f6c5a2ad6b9891..caf33746307011a6462dbd1bc5b0a7808a018813 100644 --- a/services/distributeddataservice/adapter/BUILD.gn +++ b/services/distributeddataservice/adapter/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") config("distributeddata_adapter_private_config") { visibility = [ ":*" ] @@ -20,10 +21,11 @@ config("distributeddata_adapter_private_config") { cflags = [ "-Wno-multichar" ] cflags_cc = [ "-fvisibility=hidden" ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } config("distributeddata_adapter_public_config") { - visibility = [ "//foundation/distributeddatamgr/datamgr_service:*" ] + visibility = [ ":*" ] include_dirs = [ "include/log", @@ -32,8 +34,8 @@ config("distributeddata_adapter_public_config") { "include/autils", "include/utils", "include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include/", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_path}/interfaces/innerkits/distributeddata/include/", + "${kv_store_common_path}", ] } diff --git a/services/distributeddataservice/adapter/account/BUILD.gn b/services/distributeddataservice/adapter/account/BUILD.gn index bf53ea528fdf748fba97f0283d2e7260fd926976..d2a449b8a939396f56c8312e7b37be02b0a74aac 100755 --- a/services/distributeddataservice/adapter/account/BUILD.gn +++ b/services/distributeddataservice/adapter/account/BUILD.gn @@ -26,11 +26,10 @@ ohos_static_library("distributeddata_account_static") { "../include/permission", "../include/utils", "./src", - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_common_path}", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "${ipc_core_path}/include", ] cflags_cc = [ "-fvisibility=hidden" ] @@ -59,4 +58,5 @@ ohos_static_library("distributeddata_account_static") { } subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp index b9d90b27ad542b99c75a589485f021bf1ce75665..7c6d028262f0a43fd310e207bd3adbca97bc645f 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp @@ -63,5 +63,10 @@ AccountDelegateDefaultImpl::~AccountDelegateDefaultImpl() { ZLOGD("destruct"); } + +void AccountDelegateDefaultImpl::BindExecutor(std::shared_ptr executors) +{ + ZLOGD("no account part"); +} } // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h index 1bfbcb104c78c77903c604a62a42717fb878d975..33ee5fda57579955bee2f00f007520c814873ce6 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h +++ b/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h @@ -27,6 +27,8 @@ public: bool QueryUsers(std::vector &users) override; void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; + void BindExecutor(std::shared_ptr executors) override; + private: ~AccountDelegateDefaultImpl(); }; diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp index d9e96deebaa63333218f32376bcae86d5e6ad572..5dd42f3fdf063d2eeac6ee443eee7cc0fc05c458 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp @@ -89,29 +89,25 @@ void AccountDelegateNormalImpl::SubscribeAccountEvent() account.harmonyAccountId = GetCurrentAccountId(); NotifyAccountChanged(account); }); + executors_->Execute(GetTask(0)); +} - std::thread th = std::thread([eventSubscriber = eventSubscriber_]() { - int tryTimes = 0; - constexpr int MAX_RETRY_TIME = 300; - constexpr int RETRY_WAIT_TIME_S = 1; - - // we use this method to make sure register success - while (tryTimes < MAX_RETRY_TIME) { - auto result = CommonEventManager::SubscribeCommonEvent(eventSubscriber); - if (result) { - break; - } - - ZLOGD("fail to register subscriber, error:%{public}d, time:%{public}d", result, tryTimes); - sleep(RETRY_WAIT_TIME_S); - tryTimes++; +ExecutorPool::Task AccountDelegateNormalImpl::GetTask(uint32_t retry) +{ + return [this, retry] { + auto result = CommonEventManager::SubscribeCommonEvent(eventSubscriber_); + if (result) { + ZLOGI("success to register subscriber."); + return; } - if (tryTimes == MAX_RETRY_TIME) { + ZLOGD("fail to register subscriber, error:%{public}d, time:%{public}d", result, retry); + + if (retry + 1 > MAX_RETRY_TIME) { ZLOGE("fail to register subscriber!"); + return; } - ZLOGI("success to register subscriber."); - }); - th.detach(); + executors_->Schedule(std::chrono::seconds(RETRY_WAIT_TIME_S), GetTask(retry + 1)); + }; } AccountDelegateNormalImpl::~AccountDelegateNormalImpl() @@ -152,5 +148,10 @@ std::string AccountDelegateNormalImpl::Sha256AccountId(const std::string &plainT auto plainVal = htobe64(plain); return DoHash(static_cast(&plainVal), sizeof(plainVal), true); } + +void AccountDelegateNormalImpl::BindExecutor(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h index 153dfa24f87702d299fceb6cd58e4602fa86b4af..86bdf15c95946ac4ceeee843bd16e8907774e173 100644 --- a/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h +++ b/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h @@ -19,6 +19,7 @@ #include "common_event_manager.h" #include "common_event_subscriber.h" #include "common_event_support.h" +#include "executor_pool.h" #include "log_print.h" namespace OHOS { @@ -31,11 +32,16 @@ public: bool QueryUsers(std::vector &users) override; void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; + void BindExecutor(std::shared_ptr executors) override; private: ~AccountDelegateNormalImpl(); std::string Sha256AccountId(const std::string &plainText) const; + ExecutorPool::Task GetTask(uint32_t retry); + static constexpr int MAX_RETRY_TIME = 300; + static constexpr int RETRY_WAIT_TIME_S = 1; std::shared_ptr eventSubscriber_ {}; + std::shared_ptr executors_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/adapter/account/test/BUILD.gn b/services/distributeddataservice/adapter/account/test/BUILD.gn index f0540307dcbd2788774a2056eb9daa574955be95..fa8c3d6edc219124ea89d6af7383eaf84476a4bd 100755 --- a/services/distributeddataservice/adapter/account/test/BUILD.gn +++ b/services/distributeddataservice/adapter/account/test/BUILD.gn @@ -41,6 +41,7 @@ ohos_unittest("AccountDelegateTest") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ############################################################################### diff --git a/services/distributeddataservice/adapter/autils/BUILD.gn b/services/distributeddataservice/adapter/autils/BUILD.gn index bb40ed87a5d68ce39d119e9aaec521b7e2403001..48efe8f545f9af221876c3d8477714bf09edef58 100755 --- a/services/distributeddataservice/adapter/autils/BUILD.gn +++ b/services/distributeddataservice/adapter/autils/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_autils_static") { sources = [ @@ -25,9 +26,8 @@ ohos_static_library("distributeddata_autils_static") { include_dirs = [ "../include/autils", "../include/log", - "//commonlibrary/c_utils/base/include", "../include/dfx", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_common_path}", ] cflags_cc = [ "-fvisibility=hidden" ] @@ -39,4 +39,5 @@ ohos_static_library("distributeddata_autils_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/autils/test/BUILD.gn b/services/distributeddataservice/adapter/autils/test/BUILD.gn index 283d74b86d3c61332dd29429c7086f2827f2551c..afd7c605f06a0a922cca3a0f89de40e46883e680 100755 --- a/services/distributeddataservice/adapter/autils/test/BUILD.gn +++ b/services/distributeddataservice/adapter/autils/test/BUILD.gn @@ -22,6 +22,7 @@ config("module_private_config") { "../../include/autils/", "//foundation/distributeddatamgr/kv_store/frameworks/common", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ohos_unittest("KvStoreThreadPoolTest") { diff --git a/services/distributeddataservice/adapter/broadcaster/BUILD.gn b/services/distributeddataservice/adapter/broadcaster/BUILD.gn index 387aae137dcac07bd5d1169b30a2c8586bf6e3a4..fe0fc348fa18a324750a9c9b28a4a35f69bea101 100755 --- a/services/distributeddataservice/adapter/broadcaster/BUILD.gn +++ b/services/distributeddataservice/adapter/broadcaster/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_broadcaster_static") { sources = [ @@ -22,9 +23,8 @@ ohos_static_library("distributeddata_broadcaster_static") { "../include/broadcaster", "../include/log", "./src", - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", ] cflags_cc = [ "-fvisibility=hidden" ] @@ -41,4 +41,5 @@ ohos_static_library("distributeddata_broadcaster_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/communicator/BUILD.gn b/services/distributeddataservice/adapter/communicator/BUILD.gn index 05670990c580fc1061610d352a111d6c6d8f2d7a..be70a5dda4425ec3388336297927fcfc90c380b8 100755 --- a/services/distributeddataservice/adapter/communicator/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_communicator_static") { sources = [ "src/app_pipe_handler.cpp", @@ -33,18 +34,17 @@ ohos_static_library("distributeddata_communicator_static") { ] include_dirs = [ - "//commonlibrary/c_utils/base/include", "../include/communicator", "../include/dfx", "../include/log", "../include/autils", "../include/utils", - "//foundation/communication/dsoftbus/core/common/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/relational", + "${dsoftbus_core_path}", + "${kv_store_common_path}", + "${kv_store_distributeddb_path}/interfaces/include", + "${kv_store_distributeddb_path}/include", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", ] cflags_cc = [ "-fvisibility=hidden" ] @@ -63,4 +63,5 @@ ohos_static_library("distributeddata_communicator_static") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h index ec8db4b91b6af7b43c4241a8e6f7ceb9cdceb931..5fe49b7e85b0a4c8344c85e39bd4862247f6d4de 100644 --- a/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h +++ b/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h @@ -20,7 +20,6 @@ #include #include #include -#include "task_scheduler.h" #include "log_print.h" #include "reporter.h" #include "app_data_change_listener.h" diff --git a/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp b/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp index 7f4060c89d6f03d21df4b4715dcf003cb42b0881..84d2f95a7314a7a84eb01ced8ae6b0eaca0c9049 100644 --- a/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp +++ b/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp @@ -40,7 +40,7 @@ DataBuffer::~DataBuffer() bool DataBuffer::Init(size_t size) { - if (buf_ != nullptr) { + if (buf_ != nullptr || size == 0) { return false; } size_ = std::min(size, MAX_DATA_LEN); diff --git a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index 5862e35dfb33cd014f8126839e54ce9acbd9a44f..2ea67eb8c9e03d8f6d7da5887ad2e143d4d01f86 100644 --- a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -59,17 +59,19 @@ void DataMgrDmStateCall::OnDeviceReady(const DmDeviceInfo &info) class DataMgrDmInitCall final : public DistributedHardware::DmInitCallback { public: - explicit DataMgrDmInitCall(DeviceManagerAdapter &dmAdapter) : dmAdapter_(dmAdapter) {} + explicit DataMgrDmInitCall(DeviceManagerAdapter &dmAdapter, std::shared_ptr executors) + : dmAdapter_(dmAdapter), executors_(executors) {} void OnRemoteDied() override; private: DeviceManagerAdapter &dmAdapter_; + std::shared_ptr executors_; }; void DataMgrDmInitCall::OnRemoteDied() { ZLOGI("device manager died, init again"); - dmAdapter_.Init(); + dmAdapter_.Init(executors_); } DeviceManagerAdapter::DeviceManagerAdapter() @@ -88,9 +90,12 @@ DeviceManagerAdapter &DeviceManagerAdapter::GetInstance() return dmAdapter; } -void DeviceManagerAdapter::Init() +void DeviceManagerAdapter::Init(std::shared_ptr executors) { ZLOGI("begin"); + if (executors_ == nullptr) { + executors_ = std::move(executors); + } RegDevCallback()(); } @@ -99,15 +104,14 @@ std::function DeviceManagerAdapter::RegDevCallback() return [this]() { auto &devManager = DeviceManager::GetInstance(); auto dmStateCall = std::make_shared(*this); - auto dmInitCall = std::make_shared(*this); + auto dmInitCall = std::make_shared(*this, executors_); auto resultInit = devManager.InitDeviceManager(PKG_NAME, dmInitCall); auto resultState = devManager.RegisterDevStateCallback(PKG_NAME, "", dmStateCall); if (resultInit == DM_OK && resultState == DM_OK) { return; } constexpr int32_t INTERVAL = 500; - auto time = std::chrono::steady_clock::now() + std::chrono::milliseconds(INTERVAL); - scheduler_.At(time, RegDevCallback()); + executors_->Schedule(RegDevCallback(), std::chrono::milliseconds(INTERVAL)); }; } @@ -167,8 +171,11 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE); } } - auto time = std::chrono::steady_clock::now() + std::chrono::milliseconds(SYNC_TIMEOUT); - scheduler_.At(time, [this, dvInfo]() { TimeOut(dvInfo.uuid); }); + executors_->Schedule( + std::chrono::milliseconds(SYNC_TIMEOUT), + [this, dvInfo]() { + TimeOut(dvInfo.uuid); + }); syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); for (const auto &item : observers) { // set compatible identify, sync service meta if (item == nullptr) { @@ -236,7 +243,7 @@ void DeviceManagerAdapter::Offline(const DmDeviceInfo &info) return false; }); }; - scheduler_.Execute(std::move(task)); + executors_->Execute(std::move(task)); } void DeviceManagerAdapter::OnChanged(const DmDeviceInfo &info) @@ -267,7 +274,7 @@ void DeviceManagerAdapter::OnReady(const DmDeviceInfo &info) return false; }); }; - scheduler_.Execute(std::move(task)); + executors_->Execute(std::move(task)); } bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo &dvInfo) @@ -311,7 +318,7 @@ void DeviceManagerAdapter::SaveDeviceInfo(const DeviceInfo &dvInfo, const Device DeviceInfo DeviceManagerAdapter::GetLocalDevice() { std::lock_guard lock(devInfoMutex_); - if (!localInfo_.uuid.empty()) { + if (!localInfo_.uuid.empty() && !localInfo_.udid.empty()) { return localInfo_; } @@ -324,7 +331,7 @@ DeviceInfo DeviceManagerAdapter::GetLocalDevice() auto networkId = std::string(info.networkId); auto uuid = GetUuidByNetworkId(networkId); auto udid = GetUdidByNetworkId(networkId); - if (uuid.empty() || udid.empty()) { + if (uuid.empty()) { return {}; } ZLOGI("[LocalDevice] uuid:%{public}s, name:%{public}s, type:%{public}d", @@ -467,4 +474,18 @@ std::string DeviceManagerAdapter::ToNetworkID(const std::string &id) { return GetDeviceInfoFromCache(id).networkId; } + +std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const std::string &uuid) +{ + if (uuid.empty()) { + return ""; + } + std::string encryptedUuid; + auto ret = DeviceManager::GetInstance().GenerateEncryptedUuid(PKG_NAME, uuid, appId, encryptedUuid); + if (ret != DM_OK) { + ZLOGE("failed, result:%{public}d", ret); + return ""; + } + return encryptedUuid; +} } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/adapter/communicator/test/BUILD.gn b/services/distributeddataservice/adapter/communicator/test/BUILD.gn index 318f219206bb5514c5b59120910febd72617f74d..a3fa43ac1ad48518221acd752132beaee2811fdc 100755 --- a/services/distributeddataservice/adapter/communicator/test/BUILD.gn +++ b/services/distributeddataservice/adapter/communicator/test/BUILD.gn @@ -37,6 +37,7 @@ ohos_unittest("CommunicationProviderTest") { "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", "//third_party/googletest:gtest_main", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ohos_unittest("DeviceManagerAdapterTest") { @@ -62,6 +63,7 @@ ohos_unittest("DeviceManagerAdapterTest") { "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp:devicemanagersdk", "//third_party/googletest:gtest_main", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ############################################################################### diff --git a/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp b/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp index e91ac0e449ffd252d46b95776684e347efd40490..6e0df49030359d4ac5d1015f104ae92cbe9c3714 100644 --- a/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp +++ b/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp @@ -16,6 +16,7 @@ #include "device_manager_adapter.h" #include "gtest/gtest.h" +#include "executor_pool.h" #include "types.h" namespace { using namespace testing::ext; @@ -36,7 +37,9 @@ class DeviceManagerAdapterTest : public testing::Test { public: static void SetUpTestCase(void) { - DeviceManagerAdapter::GetInstance().Init(); + size_t max = 12; + size_t min = 5; + DeviceManagerAdapter::GetInstance().Init(std::make_shared(max, min)); } static void TearDownTestCase(void) {} void SetUp() {} diff --git a/services/distributeddataservice/adapter/dfx/BUILD.gn b/services/distributeddataservice/adapter/dfx/BUILD.gn index 97d2ebde61560fdbe4169fa92fa1e12b8fd53b6e..c137b61fef10ccc8ac363a1a47f1bb7680b870c8 100644 --- a/services/distributeddataservice/adapter/dfx/BUILD.gn +++ b/services/distributeddataservice/adapter/dfx/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_dfx_static") { sources = [ @@ -34,8 +35,7 @@ ohos_static_library("distributeddata_dfx_static") { "../include/dfx", "../include/log", "../include/autils", - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_common_path}", "//third_party/openssl/include/", ] @@ -54,4 +54,5 @@ ohos_static_library("distributeddata_dfx_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp index d109c720fd78d932ea16bbce6461b5d5e31a146c..9e3b46197aa52b347f1c22de519e843dcf97cb2e 100644 --- a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp @@ -19,9 +19,13 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus BehaviourReporterImpl::Report(const BehaviourMsg &msg) { - HiViewAdapter::ReportBehaviour(DfxCodeConstant::DATABASE_BEHAVIOUR, msg); + HiViewAdapter::ReportBehaviour(DfxCodeConstant::DATABASE_BEHAVIOUR, msg, executors_); return ReportStatus::SUCCESS; } +void BehaviourReporterImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h index 0c3face27a9b2ea2b57519b2176fe4a217112cca..7ac010b1975b2847b5878086126c9bb816f80170 100644 --- a/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h @@ -25,6 +25,10 @@ class BehaviourReporterImpl : public BehaviourReporter { public: virtual ~BehaviourReporterImpl() {} ReportStatus Report(const struct BehaviourMsg &msg) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.cpp b/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.cpp index 9c1b32bedd6b3de233f224d9fe15ed008931d022..ea5b488f52829c372b08a170a83c62d9f1605610 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus CommunicationFaultImpl::Report(const CommFaultMsg &msg) { - HiViewAdapter::ReportCommFault(DfxCodeConstant::DATABASE_SYNC_FAILED, msg); + HiViewAdapter::ReportCommFault(DfxCodeConstant::DATABASE_SYNC_FAILED, msg, executors_); return ReportStatus::SUCCESS; } +void CommunicationFaultImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.h b/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.h index c78cd6790a0f09b61ad2fdec2163bb264d9a3c19..b5ec17f5815be1bed8ee0da324066da6015669dd 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/fault/communication_fault_impl.h @@ -34,6 +34,10 @@ public: return ReportStatus::SUCCESS; }; ReportStatus Report(const struct CommFaultMsg &msg) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.cpp b/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.cpp index 3e9b3de54238d34b97f5d57726cf3f797683a128..9369a31b56bf9c55839bb1cc9b3b6c761b26b237 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.cpp @@ -30,8 +30,12 @@ ReportStatus DatabaseFaultImpl::Report(const DBFaultMsg &msg) return ReportStatus::ERROR; } - HiViewAdapter::ReportDBFault(eventID, msg); + HiViewAdapter::ReportDBFault(eventID, msg, executors_); return ReportStatus::SUCCESS; } +void DatabaseFaultImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.h b/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.h index 16a054f4e6f4a099e859317527a733eca0bbf928..66c5b39be35301017ce9d7112f6e5b19f836c94f 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/fault/database_fault_impl.h @@ -33,6 +33,10 @@ public: return ReportStatus::SUCCESS; }; ReportStatus Report(const DBFaultMsg &msg) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.cpp b/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.cpp index 3fa0543a5b1417c3bc4a63bf5644315464129687..3e2dae52d05edd382c331a7a48f2ab22b3fd2170 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus RuntimeFaultImpl::Report(const FaultMsg &msg) { - HiViewAdapter::ReportFault(DfxCodeConstant::RUNTIME_FAULT, msg); + HiViewAdapter::ReportFault(DfxCodeConstant::RUNTIME_FAULT, msg, executors_); return ReportStatus::SUCCESS; } +void RuntimeFaultImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.h b/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.h index 47b20a35ce566e90e20132bd141f9e7496cb5dd7..f4aea1b0e390ec470564b36e1ac902485dcbad75 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/fault/runtime_fault_impl.h @@ -32,6 +32,10 @@ public: return ReportStatus::SUCCESS; }; ReportStatus Report(const FaultMsg &msg) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.cpp b/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.cpp index 5fb3a55f87c46d53b4ea2c9678cad75d48c580f0..b1eb464ff6f28e55a3fa88f230c0d93160df06cd 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus ServiceFaultImpl::Report(const OHOS::DistributedDataDfx::FaultMsg &msg) { - HiViewAdapter::ReportFault(DfxCodeConstant::SERVICE_FAULT, msg); + HiViewAdapter::ReportFault(DfxCodeConstant::SERVICE_FAULT, msg, executors_); return ReportStatus::SUCCESS; } +void ServiceFaultImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.h b/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.h index 4d79300cda40e5c78c29fe3025eb6d29dfb9f659..fb5eed6a89eb01d3af3af1d910964fd8549024a4 100644 --- a/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/fault/service_fault_impl.h @@ -33,6 +33,10 @@ public: return ReportStatus::SUCCESS; }; ReportStatus Report(const FaultMsg &msg) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp index 59c44c8c766a7e2eb9fea8ba3395df4013ede93d..9ac6fef2feb123a05d71f3253fcd0bd675f2d4be 100644 --- a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp +++ b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp @@ -79,12 +79,11 @@ std::mutex HiViewAdapter::apiPerformanceMutex_; std::map> HiViewAdapter::apiPerformanceStat_; bool HiViewAdapter::running_ = false; -TaskScheduler HiViewAdapter::scheduler_ {"HiView"}; std::mutex HiViewAdapter::runMutex_; -void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg) +void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg, std::shared_ptr executors) { - KvStoreTask task([dfxCode, msg]() { + ExecutorPool::Task task([dfxCode, msg]() { HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, CoverEventID(dfxCode), HiSysEvent::EventType::FAULT, @@ -93,12 +92,12 @@ void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg) INTERFACE_NAME, msg.interfaceName, ERROR_TYPE, static_cast(msg.errorType)); }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); + executors->Execute(std::move(task)); } -void HiViewAdapter::ReportDBFault(int dfxCode, const DBFaultMsg &msg) +void HiViewAdapter::ReportDBFault(int dfxCode, const DBFaultMsg &msg, std::shared_ptr executors) { - KvStoreTask task([dfxCode, msg]() { + ExecutorPool::Task task([dfxCode, msg]() { HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, CoverEventID(dfxCode), HiSysEvent::EventType::FAULT, @@ -107,13 +106,12 @@ void HiViewAdapter::ReportDBFault(int dfxCode, const DBFaultMsg &msg) MODULE_NAME, msg.moduleName, ERROR_TYPE, static_cast(msg.errorType)); }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); + executors->Execute(std::move(task)); } - -void HiViewAdapter::ReportCommFault(int dfxCode, const CommFaultMsg &msg) +void HiViewAdapter::ReportCommFault(int dfxCode, const CommFaultMsg &msg, std::shared_ptr executors) { - KvStoreTask task([dfxCode, msg]() { + ExecutorPool ::Task task([dfxCode, msg]() { std::string message; for (size_t i = 0; i < msg.deviceId.size(); i++) { message.append("No: ").append(std::to_string(i)) @@ -128,12 +126,12 @@ void HiViewAdapter::ReportCommFault(int dfxCode, const CommFaultMsg &msg) STORE_ID, msg.storeId, SYNC_ERROR_INFO, message); }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); + executors->Execute(std::move(task)); } -void HiViewAdapter::ReportBehaviour(int dfxCode, const BehaviourMsg &msg) +void HiViewAdapter::ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::shared_ptr executors) { - KvStoreTask task([dfxCode, msg]() { + ExecutorPool::Task task([dfxCode, msg]() { std::string message; message.append("Behaviour type : ").append(std::to_string(static_cast(msg.behaviourType))) .append(" behaviour info : ").append(msg.extensionInfo); @@ -145,19 +143,19 @@ void HiViewAdapter::ReportBehaviour(int dfxCode, const BehaviourMsg &msg) STORE_ID, msg.storeId, BEHAVIOUR_INFO, message); }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); + executors->Execute(std::move(task)); } -void HiViewAdapter::ReportDatabaseStatistic(int dfxCode, const DbStat &stat) +void HiViewAdapter::ReportDatabaseStatistic(int dfxCode, const DbStat &stat, std::shared_ptr executors) { - KvStoreTask task([dfxCode, stat]() { + ExecutorPool::Task task([dfxCode, stat]() { std::lock_guard lock(dbMutex_); if (!dbStat_.count(stat.GetKey())) { dbStat_.insert({stat.GetKey(), {stat, 0, dfxCode}}); } }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); - StartTimerThread(); + executors->Execute(std::move(task)); + StartTimerThread(executors); } void HiViewAdapter::ReportDbSize(const StatisticWrap &stat) @@ -205,9 +203,10 @@ void HiViewAdapter::InvokeDbSize() dbStat_.clear(); } -void HiViewAdapter::ReportTrafficStatistic(int dfxCode, const TrafficStat &stat) +void HiViewAdapter::ReportTrafficStatistic(int dfxCode, const TrafficStat &stat, + std::shared_ptr executors) { - KvStoreTask task([dfxCode, stat]() { + ExecutorPool::Task task([dfxCode, stat]() { std::lock_guard lock(trafficMutex_); auto it = trafficStat_.find(stat.GetKey()); if (it != trafficStat_.end()) { @@ -217,8 +216,8 @@ void HiViewAdapter::ReportTrafficStatistic(int dfxCode, const TrafficStat &stat) trafficStat_.insert({stat.GetKey(), {stat, 0, dfxCode}}); } }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); - StartTimerThread(); + executors->Execute(std::move(task)); + StartTimerThread(executors); } void HiViewAdapter::InvokeTraffic() @@ -243,9 +242,9 @@ void HiViewAdapter::InvokeTraffic() trafficStat_.clear(); } -void HiViewAdapter::ReportVisitStatistic(int dfxCode, const VisitStat &stat) +void HiViewAdapter::ReportVisitStatistic(int dfxCode, const VisitStat &stat, std::shared_ptr executors) { - KvStoreTask task([dfxCode, stat]() { + ExecutorPool::Task task([dfxCode, stat]() { std::lock_guard lock(visitMutex_); auto it = visitStat_.find(stat.GetKey()); if (it == visitStat_.end()) { @@ -254,8 +253,8 @@ void HiViewAdapter::ReportVisitStatistic(int dfxCode, const VisitStat &stat) it->second.times++; } }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); - StartTimerThread(); + executors->Execute(std::move(task)); + StartTimerThread(executors); } void HiViewAdapter::InvokeVisit() @@ -273,9 +272,10 @@ void HiViewAdapter::InvokeVisit() visitStat_.clear(); } -void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat) +void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat, + std::shared_ptr executors) { - KvStoreTask task([dfxCode, stat]() { + ExecutorPool::Task task([dfxCode, stat]() { std::lock_guard lock(apiPerformanceMutex_); auto it = apiPerformanceStat_.find(stat.GetKey()); if (it == apiPerformanceStat_.end()) { @@ -294,8 +294,8 @@ void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerforma } }); - scheduler_.At(std::chrono::steady_clock::now(), std::move(task)); - StartTimerThread(); + executors->Execute(std::move(task)); + StartTimerThread(executors); } void HiViewAdapter::InvokeApiPerformance() @@ -319,7 +319,7 @@ void HiViewAdapter::InvokeApiPerformance() ZLOGI("DdsTrace interface: clean"); } -void HiViewAdapter::StartTimerThread() +void HiViewAdapter::StartTimerThread(std::shared_ptr executors) { if (running_) { return; @@ -329,8 +329,7 @@ void HiViewAdapter::StartTimerThread() return; } running_ = true; - std::chrono::duration delay(0); - std::chrono::duration internal(WAIT_TIME); + auto interval = std::chrono::seconds(WAIT_TIME); auto fun = []() { time_t current = time(nullptr); tm localTime = { 0 }; @@ -342,7 +341,7 @@ void HiViewAdapter::StartTimerThread() InvokeTraffic(); InvokeVisit(); }; - scheduler_.Every(delay, internal, fun); + executors->Schedule(fun, interval); } std::string HiViewAdapter::CoverEventID(int dfxCode) diff --git a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h index d7c57f93d0baadb1745152477fe86fe4994e07c1..21de2703b9b2a71fa5e27aae92885d205d168fc7 100644 --- a/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h +++ b/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h @@ -18,12 +18,11 @@ #include #include -#include "dfx_types.h" + #include "dfx_code_constant.h" +#include "dfx_types.h" +#include "executor_pool.h" #include "hisysevent.h" -#include "task_scheduler.h" -#include "kv_store_thread_pool.h" -#include "kv_store_task.h" #include "value_hash.h" namespace OHOS { @@ -38,15 +37,16 @@ struct StatisticWrap { class HiViewAdapter { public: ~HiViewAdapter(); - static void ReportFault(int dfxCode, const FaultMsg &msg); - static void ReportDBFault(int dfxCode, const DBFaultMsg &msg); - static void ReportCommFault(int dfxCode, const CommFaultMsg &msg); - static void ReportVisitStatistic(int dfxCode, const VisitStat &stat); - static void ReportTrafficStatistic(int dfxCode, const TrafficStat &stat); - static void ReportDatabaseStatistic(int dfxCode, const DbStat &stat); - static void ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat); - static void ReportBehaviour(int dfxCode, const BehaviourMsg &msg); - static void StartTimerThread(); + static void ReportFault(int dfxCode, const FaultMsg &msg, std::shared_ptr executors); + static void ReportDBFault(int dfxCode, const DBFaultMsg &msg, std::shared_ptr executors); + static void ReportCommFault(int dfxCode, const CommFaultMsg &msg, std::shared_ptr executors); + static void ReportVisitStatistic(int dfxCode, const VisitStat &stat, std::shared_ptr executors); + static void ReportTrafficStatistic(int dfxCode, const TrafficStat &stat, std::shared_ptr executors); + static void ReportDatabaseStatistic(int dfxCode, const DbStat &stat, std::shared_ptr executors); + static void ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat, + std::shared_ptr executors); + static void ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::shared_ptr executors); + static void StartTimerThread(std::shared_ptr executors); private: static std::mutex visitMutex_; @@ -70,7 +70,6 @@ private: private: static std::mutex runMutex_; static bool running_; - static TaskScheduler scheduler_; static const inline int DAILY_REPORT_TIME = 23; static const inline int WAIT_TIME = 1 * 60 * 60; // 1 hours }; diff --git a/services/distributeddataservice/adapter/dfx/src/reporter.cpp b/services/distributeddataservice/adapter/dfx/src/reporter.cpp index 41b96ab31a5af5921fb4bf20dea71bb4e66785da..63102aecb51a04c8bbf5d34153f97958139739d3 100644 --- a/services/distributeddataservice/adapter/dfx/src/reporter.cpp +++ b/services/distributeddataservice/adapter/dfx/src/reporter.cpp @@ -37,54 +37,63 @@ Reporter* Reporter::GetInstance() FaultReporter* Reporter::CommunicationFault() { static CommunicationFaultImpl communicationFault; + communicationFault.SetThreadPool(executors_); return &communicationFault; } FaultReporter* Reporter::DatabaseFault() { static DatabaseFaultImpl databaseFault; + databaseFault.SetThreadPool(executors_); return &databaseFault; } FaultReporter* Reporter::RuntimeFault() { static RuntimeFaultImpl runtimeFault; + runtimeFault.SetThreadPool(executors_); return &runtimeFault; } FaultReporter* Reporter::ServiceFault() { static ServiceFaultImpl serviceFault; + serviceFault.SetThreadPool(executors_); return &serviceFault; } StatisticReporter* Reporter::TrafficStatistic() { static TrafficStatisticImpl trafficStatistic; + trafficStatistic.SetThreadPool(executors_); return &trafficStatistic; } StatisticReporter* Reporter::VisitStatistic() { static VisitStatisticImpl visitStatistic; + visitStatistic.SetThreadPool(executors_); return &visitStatistic; } StatisticReporter* Reporter::DatabaseStatistic() { static DatabaseStatisticImpl databaseStatistic; + databaseStatistic.SetThreadPool(executors_); return &databaseStatistic; } StatisticReporter* Reporter::ApiPerformanceStatistic() { static ApiPerformanceStatisticImpl apiPerformanceStat; + apiPerformanceStat.SetThreadPool(executors_); return &apiPerformanceStat; } BehaviourReporter* Reporter::BehaviourReporter() { static BehaviourReporterImpl behaviourReporterImpl; + behaviourReporterImpl.SetThreadPool(executors_); return &behaviourReporterImpl; } } // namespace DistributedDataDfx diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.cpp b/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.cpp index 9e7d78977738ab86c1225e56f5dbc61f93f96a95..0bf922a10eaa51083ee03c1a134820fc11a729d9 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.cpp @@ -19,9 +19,13 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus ApiPerformanceStatisticImpl::Report(const ApiPerformanceStat &stat) { - HiViewAdapter::ReportApiPerformanceStatistic(DfxCodeConstant::API_PERFORMANCE_INTERFACE, stat); + HiViewAdapter::ReportApiPerformanceStatistic(DfxCodeConstant::API_PERFORMANCE_INTERFACE, stat, executors_); return ReportStatus::SUCCESS; } +void ApiPerformanceStatisticImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.h b/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.h index 36692d955801cd031a1a2878f2c3797230428e04..f253ee7b38c2d116c2b103166ca72aff31bd724a 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/statistic/api_performance_statistic_impl.h @@ -26,6 +26,10 @@ class ApiPerformanceStatisticImpl : public StatisticReporter public: virtual ~ApiPerformanceStatisticImpl() {} ReportStatus Report(const ApiPerformanceStat &stat) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.cpp b/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.cpp index 9ffa814b5dfaaec8eaed2dac9b4edf68e9350fbd..070e1828d7c9ab01b071600c7cf6560fbfb8a8ba 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus DatabaseStatisticImpl::Report(const DbStat &stat) { - HiViewAdapter::ReportDatabaseStatistic(DfxCodeConstant::DATABASE_STATISTIC, stat); + HiViewAdapter::ReportDatabaseStatistic(DfxCodeConstant::DATABASE_STATISTIC, stat, executors_); return ReportStatus::SUCCESS; } +void DatabaseStatisticImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.h b/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.h index c3e907636a54d437d463e5fe91c12e3b04b5107c..c3aa6774d2cf988dd440713ff59a4dc2a38bd0dc 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/statistic/database_statistic_impl.h @@ -25,6 +25,10 @@ class DatabaseStatisticImpl : public StatisticReporter { public: virtual ~DatabaseStatisticImpl() {} ReportStatus Report(const DbStat &stat) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.cpp b/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.cpp index 2821a6e242d2f921144abcf49f1578fb42045dcb..0ee80df4055e70a9846fac523b1194e5a096f46b 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus TrafficStatisticImpl::Report(const TrafficStat &stat) { - HiViewAdapter::ReportTrafficStatistic(DfxCodeConstant::TRAFFIC_STATISTIC, stat); + HiViewAdapter::ReportTrafficStatistic(DfxCodeConstant::TRAFFIC_STATISTIC, stat, executors_); return ReportStatus::SUCCESS; } +void TrafficStatisticImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.h b/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.h index 3961b1c37bee1b19b48535fe31030b4c9d92c4f8..c65e888889b5580ce97bc963d171ee12322e43c0 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/statistic/traffic_statistic_impl.h @@ -25,6 +25,10 @@ class TrafficStatisticImpl : public StatisticReporter { public: virtual ~TrafficStatisticImpl() {} ReportStatus Report(const TrafficStat &stat) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.cpp b/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.cpp index 8b86b73352cfec9e2402b253f88bf5c5f54db70d..99536be807735994c546766eff613703277f183d 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.cpp +++ b/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.cpp @@ -19,8 +19,12 @@ namespace OHOS { namespace DistributedDataDfx { ReportStatus VisitStatisticImpl::Report(const VisitStat &stat) { - HiViewAdapter::ReportVisitStatistic(DfxCodeConstant::VISIT_STATISTIC, stat); + HiViewAdapter::ReportVisitStatistic(DfxCodeConstant::VISIT_STATISTIC, stat, executors_); return ReportStatus::SUCCESS; } +void VisitStatisticImpl::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.h b/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.h index fed8ab728edc526f4c51e60a93c644597f51f4e0..fb5b933ec46d3e669bfdf5adb586741b4feb8582 100644 --- a/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.h +++ b/services/distributeddataservice/adapter/dfx/src/statistic/visit_statistic_impl.h @@ -25,6 +25,10 @@ class VisitStatisticImpl : public StatisticReporter { public: virtual ~VisitStatisticImpl() {} ReportStatus Report(const VisitStat &stat) override; + void SetThreadPool(std::shared_ptr executors); + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/dfx/test/BUILD.gn b/services/distributeddataservice/adapter/dfx/test/BUILD.gn index 3ae42016400871f89577dc63ed7f74e4a5938fe2..de03ed064b9eed0b936d296c663657709d68b62d 100755 --- a/services/distributeddataservice/adapter/dfx/test/BUILD.gn +++ b/services/distributeddataservice/adapter/dfx/test/BUILD.gn @@ -52,6 +52,7 @@ ohos_unittest("DistributeddataDfxMSTTest") { "//third_party/googletest:gtest_main", "//third_party/openssl:libcrypto_shared", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ############################################################################### @@ -109,6 +110,7 @@ ohos_unittest("DistributeddataDfxUTTest") { "//third_party/googletest:gtest_main", "//third_party/openssl:libcrypto_shared", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ############################################################################### @@ -116,9 +118,6 @@ group("unittest") { testonly = true deps = [] - deps += [ - ":DistributeddataDfxMSTTest", - ":DistributeddataDfxUTTest", - ] + deps += [ ":DistributeddataDfxMSTTest" ] } ############################################################################### diff --git a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_mst_test.cpp b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_mst_test.cpp index 521ad0f92c1558e60fc6f324cbcd290b9478b5e0..5945937fb2dccb2031f72402a7bacef956e597a8 100644 --- a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_mst_test.cpp +++ b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_mst_test.cpp @@ -31,9 +31,17 @@ public: void TearDown(); }; -void DistributedataDfxMSTTest::SetUpTestCase() {} +void DistributedataDfxMSTTest::SetUpTestCase() +{ + size_t max = 12; + size_t min = 5; + Reporter::GetInstance()->SetThreadPool(std::make_shared(max, min)); +} -void DistributedataDfxMSTTest::TearDownTestCase() {} +void DistributedataDfxMSTTest::TearDownTestCase() +{ + Reporter::GetInstance()->SetThreadPool(nullptr); +} void DistributedataDfxMSTTest::SetUp() {} diff --git a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp index f0ee9682d0b36db2c79ce6b769ecbce13dafd8b2..b93b5632b3c6d06f0061b8bca27805aabe16f3c0 100644 --- a/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp +++ b/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp @@ -35,11 +35,15 @@ public: void DistributedataDfxUTTest::SetUpTestCase() { + size_t max = 12; + size_t min = 5; + Reporter::GetInstance()->SetThreadPool(std::make_shared(max, min)); FakeHivew::Clear(); } void DistributedataDfxUTTest::TearDownTestCase() { + Reporter::GetInstance()->SetThreadPool(nullptr); FakeHivew::Clear(); } diff --git a/services/distributeddataservice/adapter/include/account/account_delegate.h b/services/distributeddataservice/adapter/include/account/account_delegate.h index d7fa49da5c8dc0e6db0d7904a62aba99c48f0994..79cdb36d464a8412597edb194d34633183d99c94 100644 --- a/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/services/distributeddataservice/adapter/include/account/account_delegate.h @@ -18,6 +18,7 @@ #include #include +#include "executor_pool.h" #include "types.h" #include "visibility.h" @@ -62,6 +63,7 @@ public: API_EXPORT virtual void UnsubscribeAccountEvent() = 0; API_EXPORT virtual bool QueryUsers(std::vector &users) = 0; API_EXPORT virtual bool RegisterHashFunc(HashFunc hash) = 0; + API_EXPORT virtual void BindExecutor(std::shared_ptr executors) = 0; API_EXPORT static AccountDelegate *GetInstance(); private: diff --git a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h index 0fc8a548848a8650b7f04a1c617ea941fa8d7caf..9cb05a88287f92328ccc43401e6d0a7d54da3648 100644 --- a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h +++ b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h @@ -25,7 +25,7 @@ #include "device_manager.h" #include "device_manager_callback.h" #include "dm_device_info.h" -#include "task_scheduler.h" +#include "executor_pool.h" #include "lru_bucket.h" namespace OHOS { @@ -33,13 +33,13 @@ namespace DistributedData { class API_EXPORT DeviceManagerAdapter { public: using DmDeviceInfo = OHOS::DistributedHardware::DmDeviceInfo; - using KvScheduler = OHOS::TaskScheduler; using DeviceInfo = OHOS::AppDistributedKv::DeviceInfo; using PipeInfo = OHOS::AppDistributedKv::PipeInfo; using AppDeviceChangeListener = OHOS::AppDistributedKv::AppDeviceChangeListener; using Status = OHOS::DistributedKv::Status; static DeviceManagerAdapter &GetInstance(); - void Init(); + + void Init(std::shared_ptr executors); Status StartWatchDeviceChange(const AppDeviceChangeListener *observer, const PipeInfo &pipeInfo); Status StopWatchDeviceChange(const AppDeviceChangeListener *observer, const PipeInfo &pipeInfo); DeviceInfo GetLocalDevice(); @@ -47,6 +47,7 @@ public: DeviceInfo GetDeviceInfo(const std::string &id); std::string GetUuidByNetworkId(const std::string &networkId); std::string GetUdidByNetworkId(const std::string &networkId); + std::string CalcClientUuid(const std::string &appId, const std::string &uuid); std::string ToUUID(const std::string &id); std::string ToUDID(const std::string &id); static std::vector ToUUID(const std::vector &devices); @@ -75,9 +76,9 @@ private: ConcurrentMap observers_ {}; LRUBucket deviceInfos_ {64}; static constexpr size_t TIME_TASK_CAPACITY = 50; - KvScheduler scheduler_ {TIME_TASK_CAPACITY, "dm_adapter"}; static constexpr int32_t SYNC_TIMEOUT = 10 * 1000; // ms ConcurrentMap syncTask_ {}; + std::shared_ptr executors_; }; } // namespace DistributedData } // namespace OHOS diff --git a/services/distributeddataservice/adapter/include/dfx/reporter.h b/services/distributeddataservice/adapter/include/dfx/reporter.h index 8adb5bd6a16c0fc961066e0d63ba1f6d418c1776..f84af98ae02429b9dbb108a0547a0a286bd70a02 100644 --- a/services/distributeddataservice/adapter/include/dfx/reporter.h +++ b/services/distributeddataservice/adapter/include/dfx/reporter.h @@ -22,6 +22,7 @@ #include "statistic_reporter.h" #include "fault_reporter.h" #include "behaviour_reporter.h" +#include "executor_pool.h" namespace OHOS { namespace DistributedDataDfx { @@ -39,6 +40,13 @@ public: KVSTORE_API StatisticReporter* ApiPerformanceStatistic(); KVSTORE_API BehaviourReporter* BehaviourReporter(); + void SetThreadPool(std::shared_ptr executors) + { + executors_ = executors; + }; + +private: + std::shared_ptr executors_; }; } // namespace DistributedDataDfx } // namespace OHOS diff --git a/services/distributeddataservice/adapter/permission/BUILD.gn b/services/distributeddataservice/adapter/permission/BUILD.gn index c6f96a2a26c774efe3eb8b9baa45fb999324f415..48e7792729a88cd4c0a65108c0645116ba273ced 100644 --- a/services/distributeddataservice/adapter/permission/BUILD.gn +++ b/services/distributeddataservice/adapter/permission/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_permission_static") { sources = [ "src/permission_validator.cpp" ] @@ -20,9 +21,8 @@ ohos_static_library("distributeddata_permission_static") { include_dirs = [ "../include/permission", "../include/utils", - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", ] @@ -39,4 +39,5 @@ ohos_static_library("distributeddata_permission_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/adapter/permission/test/BUILD.gn b/services/distributeddataservice/adapter/permission/test/BUILD.gn index 0c85975857949bd32f76f42254cc53f70f598a70..a19f4c30fdd885df876c31c845aa60eb9a77ed61 100644 --- a/services/distributeddataservice/adapter/permission/test/BUILD.gn +++ b/services/distributeddataservice/adapter/permission/test/BUILD.gn @@ -43,6 +43,7 @@ ohos_unittest("PermissionValidatorTest") { ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } group("unittest") { diff --git a/services/distributeddataservice/adapter/utils/BUILD.gn b/services/distributeddataservice/adapter/utils/BUILD.gn index cd85ee93a104f2e9706674414c9692263d4a7c33..b57d430bb0024e90d3d89eb9714d1db9e93e3422 100755 --- a/services/distributeddataservice/adapter/utils/BUILD.gn +++ b/services/distributeddataservice/adapter/utils/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_utils_static") { sources = [ "src/kvstore_utils.cpp" ] @@ -26,10 +27,9 @@ ohos_static_library("distributeddata_utils_static") { "../include/utils", "../include/log", "../include/communicator", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//commonlibrary/c_utils/base/include", "../include/dfx", - "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${kv_store_common_path}", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] @@ -39,4 +39,5 @@ ohos_static_library("distributeddata_utils_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index 3e962580716483315106e657518b752ad80687f4..6fa9ba6aa580f0f6ca556fb9c7deea240e25ef41 100644 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -38,8 +38,8 @@ ohos_sa_profile("distributeddata_profile") { config("module_private_config") { visibility = [ ":*" ] include_dirs = [ - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/config/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/crypto/include", @@ -50,9 +50,8 @@ config("module_private_config") { "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/backup/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/kvdb", - "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", - "//utils/system/safwk/native/include", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "${distributedfilejs_path}/interfaces/kits/js/src/mod_securitylabel", "../adapter/include/account", "../adapter/include/permission", "../adapter/include/uninstaller", @@ -60,10 +59,8 @@ config("module_private_config") { "../adapter/include/utils", "../adapter/include/dfx", "../adapter/include", - "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include", # for ipc_core interfaces. - "//commonlibrary/c_utils/base/include", "include", "src", "src/security", @@ -89,6 +86,7 @@ ohos_shared_library("distributeddataservice") { "src/session_manager/route_head_handler_impl.cpp", "src/session_manager/session_manager.cpp", "src/session_manager/upgrade_manager.cpp", + "src/task_manager.cpp", ] if (datamgr_service_power) { @@ -101,6 +99,7 @@ ohos_shared_library("distributeddataservice") { configs = [ ":module_private_config" ] deps = [ + "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -109,8 +108,6 @@ ohos_shared_library("distributeddataservice") { "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/uninstaller:distributeddata_uninstaller_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", ] external_deps = [ @@ -126,6 +123,7 @@ ohos_shared_library("distributeddataservice") { "hitrace_native:libhitracechain", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "kv_store:distributeddata_inner", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] @@ -140,4 +138,5 @@ ohos_shared_library("distributeddataservice") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/app/distributed_data.cfg b/services/distributeddataservice/app/distributed_data.cfg index 494bc79bf2a42f71ed981de3fae6f6cead270de6..3c0eb54e128659550dea6f619eab4b84b10c49d2 100644 --- a/services/distributeddataservice/app/distributed_data.cfg +++ b/services/distributeddataservice/app/distributed_data.cfg @@ -29,9 +29,11 @@ "secon" : "u:r:distributeddata:s0", "apl" : "system_basic", "permission" : [ - "ohos.permission.DISTRIBUTED_DATASYNC", - "ohos.permission.MANAGE_LOCAL_ACCOUNTS" + "ohos.permission.DISTRIBUTED_DATASYNC", + "ohos.permission.MANAGE_LOCAL_ACCOUNTS", + "ohos.permission.ACCESS_SERVICE_DM", + "ohos.permission.PROXY_AUTHORIZATION_URI" ] } ] -} +} \ No newline at end of file diff --git a/services/distributeddataservice/app/src/checker/BUILD.gn b/services/distributeddataservice/app/src/checker/BUILD.gn index 6bf706d95da71caa6b0f016da027437aa0e1cc68..1f59492cac8717e5eb1cff7ae28164ceff672cd3 100644 --- a/services/distributeddataservice/app/src/checker/BUILD.gn +++ b/services/distributeddataservice/app/src/checker/BUILD.gn @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_checker_static") { sources = [ @@ -21,10 +22,9 @@ ohos_static_library("distributeddata_checker_static") { cflags_cc = [ "-fvisibility=hidden" ] include_dirs = [ - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", ] if (build_public_version) { @@ -46,4 +46,5 @@ ohos_static_library("distributeddata_checker_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/app/src/feature_stub_impl.cpp b/services/distributeddataservice/app/src/feature_stub_impl.cpp index 06cd7ee30a83cd4ab3cfdb02ebd8f5dde627cd8a..01171f9513cfb78b60cc0e22d16dffa5e00d3954 100644 --- a/services/distributeddataservice/app/src/feature_stub_impl.cpp +++ b/services/distributeddataservice/app/src/feature_stub_impl.cpp @@ -32,11 +32,12 @@ int FeatureStubImpl::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return featureImpl_->OnRemoteRequest(code, data, reply); } -int32_t FeatureStubImpl::OnInitialize() +int32_t FeatureStubImpl::OnInitialize(std::shared_ptr executor) { if (featureImpl_ == nullptr) { return -1; } + featureImpl_->OnExecutor(std::move(executor)); return featureImpl_->OnInitialize(); } @@ -95,4 +96,4 @@ int32_t FeatureStubImpl::OnReady(const std::string &device) } return featureImpl_->OnReady(device); } -} \ No newline at end of file +} diff --git a/services/distributeddataservice/app/src/feature_stub_impl.h b/services/distributeddataservice/app/src/feature_stub_impl.h index 4e4562df5977024b4a702058824009f7b44e96af..6fc9c824b5960dd27f1001c66aee93ae0285e4bd 100644 --- a/services/distributeddataservice/app/src/feature_stub_impl.h +++ b/services/distributeddataservice/app/src/feature_stub_impl.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_APP_FEATURE_STUB_IMPL_H #define OHOS_DISTRIBUTED_DATA_APP_FEATURE_STUB_IMPL_H +#include "executor_pool.h" #include "feature/feature_system.h" #include "iremote_stub.h" namespace OHOS::DistributedData { @@ -29,7 +30,7 @@ public: ~FeatureStubImpl(); int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - int32_t OnInitialize(); + int32_t OnInitialize(std::shared_ptr executor); int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName); int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); diff --git a/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn b/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn index cf921d03ed7e640eaaaca32fc2b3215b0b5d9ee4..61f307283ca76fb291cbaf2e631358958f68d5a3 100755 --- a/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn +++ b/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_flowctrl_static") { sources = [ "kvstore_flowctrl_manager.cpp" ] @@ -19,8 +20,8 @@ ohos_static_library("distributeddata_flowctrl_static") { include_dirs = [ "../../../adapter/include/account", "../../src", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//third_party/json/single_include", "//commonlibrary/c_utils/base/include", ] @@ -31,4 +32,5 @@ ohos_static_library("distributeddata_flowctrl_static") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/app/src/kvstore_account_observer.cpp b/services/distributeddataservice/app/src/kvstore_account_observer.cpp index f8258225511affad7909ed7dcbb73977d1b0fe73..4c6f0be5b3b881d7287ec1c1a547a5864435d5bb 100644 --- a/services/distributeddataservice/app/src/kvstore_account_observer.cpp +++ b/services/distributeddataservice/app/src/kvstore_account_observer.cpp @@ -17,7 +17,6 @@ #include "kvstore_account_observer.h" #include -#include "executor_factory.h" #include "kvstore_data_service.h" #include "log_print.h" @@ -27,11 +26,11 @@ std::atomic g_kvStoreAccountEventStatus {0}; void KvStoreAccountObserver::OnAccountChanged(const AccountEventInfo &eventInfo) { ZLOGI("account event %d, begin.", eventInfo.status); - KvStoreTask task([this, eventInfo]() { + ExecutorPool::Task task([this, eventInfo]() { ZLOGI("account event processing in thread"); kvStoreDataService_.AccountEventChanged(eventInfo); }); - DistributedData::ExecutorFactory::GetInstance().Execute(std::move(task)); + executors_->Execute(std::move(task)); ZLOGI("account event %d, end.", eventInfo.status); } } // namespace DistributedKv diff --git a/services/distributeddataservice/app/src/kvstore_account_observer.h b/services/distributeddataservice/app/src/kvstore_account_observer.h index ddc4103df6e47cf3cf7f697947422478a7cd3278..a0598ec0439273d82617e64826dae8c4bdc065f3 100644 --- a/services/distributeddataservice/app/src/kvstore_account_observer.h +++ b/services/distributeddataservice/app/src/kvstore_account_observer.h @@ -17,7 +17,9 @@ #define KVSTORE_ACCOUNT_OBSERVER_H #include + #include "account_delegate.h" +#include "executor_pool.h" namespace OHOS { namespace DistributedKv { @@ -32,8 +34,11 @@ do { \ class KvStoreDataService; class KvStoreAccountObserver : public AccountDelegate::Observer { public: - explicit KvStoreAccountObserver(KvStoreDataService &kvStoreDataService) - : kvStoreDataService_(kvStoreDataService) {} + explicit KvStoreAccountObserver(KvStoreDataService &kvStoreDataService, + std::shared_ptr executors) + : kvStoreDataService_(kvStoreDataService), executors_(executors) + { + } ~KvStoreAccountObserver() override = default; void OnAccountChanged(const AccountEventInfo &eventInfo) override; @@ -50,6 +55,7 @@ public: private: KvStoreDataService &kvStoreDataService_; + std::shared_ptr executors_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index c9138c6573d3880450b758c02c67015ab4cfe65d..ee5ef9e7b90aebcd78d88e1f1d143ab652da1c31 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -30,21 +30,24 @@ #include "device_manager_adapter.h" #include "device_matrix.h" #include "eventcenter/event_center.h" -#include "executor_factory.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "kvstore_account_observer.h" #include "log_print.h" +#include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" #include "permission_validator.h" #include "permit_delegate.h" #include "process_communicator_impl.h" +#include "reporter.h" #include "route_head_handler_impl.h" #include "runtime_config.h" #include "string_ex.h" #include "system_ability_definition.h" +#include "task_manager.h" #include "uninstaller/uninstaller.h" +#include "upgrade.h" #include "upgrade_manager.h" #include "user_delegate.h" #include "utils/block_integer.h" @@ -57,6 +60,7 @@ using namespace OHOS::DistributedDataDfx; using KvStoreDelegateManager = DistributedDB::KvStoreDelegateManager; using SecretKeyMeta = DistributedData::SecretKeyMetaData; using DmAdapter = DistributedData::DeviceManagerAdapter; +using DBConfig = DistributedDB::RuntimeConfig; REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true); @@ -87,21 +91,35 @@ void KvStoreDataService::Initialize() #endif auto communicator = std::make_shared(RouteHeadHandlerImpl::Create); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); + DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared(executors_)); ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); AppDistributedKv::CommunicationProvider::GetInstance(); PermitDelegate::GetInstance().Init(); - InitSecurityAdapter(); + InitSecurityAdapter(executors_); + KvStoreMetaManager::GetInstance().BindExecutor(executors_); KvStoreMetaManager::GetInstance().InitMetaParameter(); - accountEventObserver_ = std::make_shared(*this); + accountEventObserver_ = std::make_shared(*this, executors_); AccountDelegate::GetInstance()->Subscribe(accountEventObserver_); deviceInnerListener_ = std::make_unique(*this); DmAdapter::GetInstance().StartWatchDeviceChange(deviceInnerListener_.get(), { "innerListener" }); + auto translateCall = [](const std::string &oriDevId, const DistributedDB::StoreInfo &info) { + StoreMetaData meta; + AppIDMetaData appIdMeta; + MetaDataManager::GetInstance().LoadMeta(info.appId, appIdMeta, true); + meta.bundleName = appIdMeta.bundleName; + meta.storeId = info.storeId; + meta.user = info.userId; + meta.deviceId = oriDevId; + MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta); + return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta); + }; + DBConfig::SetTranslateToDeviceIdCallback(translateCall); } sptr KvStoreDataService::GetFeatureInterface(const std::string &name) { - sptr feature; + sptr feature; bool isFirstCreate = false; features_.Compute(name, [&feature, &isFirstCreate](const auto &key, auto &value) ->bool { if (value != nullptr) { @@ -117,21 +135,24 @@ sptr KvStoreDataService::GetFeatureInterface(const std::string &n return false; } - value = new DistributedData::FeatureStubImpl(impl); + value = new FeatureStubImpl(impl); feature = value; isFirstCreate = true; return true; }); if (isFirstCreate) { - feature->OnInitialize(); + feature->OnInitialize(executors_); } return feature != nullptr ? feature->AsObject() : nullptr; } -void KvStoreDataService::InitObjectStore() +void KvStoreDataService::LoadFeatures() { ZLOGI("begin."); - auto feature = GetFeatureInterface("data_object"); + auto features = FeatureSystem::GetInstance().GetFeatureName(FeatureSystem::BIND_NOW); + for (auto &feature : features) { + GetFeatureInterface(feature); + } } /* RegisterClientDeathObserver */ @@ -212,8 +233,13 @@ void KvStoreDataService::OnStart() { ZLOGI("distributeddata service onStart"); EventCenter::Defer defer; + constexpr size_t MAX = 12; + constexpr size_t MIN = 5; + executors_ = std::make_shared(MAX, MIN); + Reporter::GetInstance()->SetThreadPool(executors_); + AccountDelegate::GetInstance()->BindExecutor(executors_); AccountDelegate::GetInstance()->RegisterHashFunc(Crypto::Sha256); - DmAdapter::GetInstance().Init(); + DmAdapter::GetInstance().Init(executors_); static constexpr int32_t RETRY_TIMES = 50; static constexpr int32_t RETRY_INTERVAL = 500 * 1000; // unit is ms for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIMES; ++retry) { @@ -227,7 +253,7 @@ void KvStoreDataService::OnStart() Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); Bootstrap::GetInstance().LoadNetworks(); - Bootstrap::GetInstance().LoadBackup(); + Bootstrap::GetInstance().LoadBackup(executors_); Initialize(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr != nullptr) { @@ -251,7 +277,7 @@ void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std:: return; } AccountDelegate::GetInstance()->SubscribeAccountEvent(); - Uninstaller::GetInstance().Init(this); + Uninstaller::GetInstance().Init(this, executors_); } void KvStoreDataService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) @@ -271,22 +297,20 @@ void KvStoreDataService::StartService() ZLOGI("begin."); KvStoreMetaManager::GetInstance().InitMetaListener(); DeviceMatrix::GetInstance().Initialize(IPCSkeleton::GetCallingTokenID(), Bootstrap::GetInstance().GetMetaDBName()); - InitObjectStore(); + LoadFeatures(); bool ret = SystemAbility::Publish(this); if (!ret) { DumpHelper::GetInstance().AddErrorInfo("StartService: Service publish failed."); } - Uninstaller::GetInstance().Init(this); // Initialize meta db delegate manager. KvStoreMetaManager::GetInstance().SubscribeMeta(KvStoreMetaRow::KEY_PREFIX, [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { OnStoreMetaChanged(key, value, flag); }); - UpgradeManager::GetInstance().Init(); - UserDelegate::GetInstance().Init(); + UpgradeManager::GetInstance().Init(executors_); + UserDelegate::GetInstance().Init(executors_); // subscribe account event listener to EventNotificationMgr - AccountDelegate::GetInstance()->SubscribeAccountEvent(); auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -> bool { auto status = ResolveAutoLaunchParamByIdentifier(identifier, param); features_.ForEachCopies([&identifier, ¶m](const auto &, sptr &value) { @@ -435,14 +459,13 @@ void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeM store = delegate; } }); - KvStoreTask delayTask([store]() { - constexpr const int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds - std::this_thread::sleep_for(std::chrono::seconds(CLOSE_STORE_DELAY_TIME)); + ExecutorPool::Task delayTask([store]() { ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied"); DistributedDB::KvStoreDelegateManager delegateManager("", ""); delegateManager.CloseKvStore(store); }); - ExecutorFactory::GetInstance().Execute(std::move(delayTask)); + constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds + executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask)); } Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector &cipherKey, @@ -594,11 +617,11 @@ void KvStoreDataService::NotifyAccountEvent(const AccountEventInfo &eventInfo) } } -void KvStoreDataService::InitSecurityAdapter() +void KvStoreDataService::InitSecurityAdapter(std::shared_ptr executors) { auto ret = DATASL_OnStart(); ZLOGI("datasl on start ret:%d", ret); - security_ = std::make_shared(); + security_ = std::make_shared(executors); if (security_ == nullptr) { ZLOGE("security is nullptr."); return; diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index 990f4500cfc75e95748d16705d602742bfc0d9b1..fae1dbac481000ad378d095995a224e78cf46253 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -22,16 +22,19 @@ #include "account_delegate.h" #include "constant.h" +#include "dump_helper.h" +#include "feature_stub_impl.h" #include "ikvstore_data_service.h" +#include "ithread_pool.h" #include "kvstore_device_listener.h" #include "kvstore_meta_manager.h" #include "metadata/store_meta_data.h" #include "reporter.h" +#include "runtime_config.h" #include "security/security.h" #include "system_ability.h" +#include "executor_pool.h" #include "types.h" -#include "dump_helper.h" -#include "feature_stub_impl.h" namespace OHOS::DistributedKv { class KvStoreAccountObserver; @@ -105,18 +108,18 @@ private: void Initialize(); - void InitObjectStore(); + void LoadFeatures(); void StartService(); - void InitSecurityAdapter(); + void InitSecurityAdapter(std::shared_ptr executors); void OnStoreMetaChanged(const std::vector &key, const std::vector &value, CHANGE_FLAG flag); Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId); bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); - static void ResolveAutoLaunchCompatible(const StoreMetaData &meta, const std::string &identifier); + void ResolveAutoLaunchCompatible(const StoreMetaData &meta, const std::string &identifier); static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, DistributedDB::KvStoreNbDelegate::Option &dbOption); @@ -130,6 +133,7 @@ private: std::shared_ptr security_; ConcurrentMap> features_; std::shared_ptr deviceInnerListener_; + std::shared_ptr executors_; }; class DbMetaCallbackDelegateMgr : public DbMetaCallbackDelegate { diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 91c77d7c2ce1af99ba77e0b393dc1ce3cfa7d61c..7fb54c86a5cda403e517ca0575dcdaf15e2d9363 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -172,30 +172,33 @@ void KvStoreMetaManager::InitMetaData() void KvStoreMetaManager::InitMetaParameter() { ZLOGI("start."); - std::thread th = std::thread([]() { - constexpr int32_t RETRY_MAX_TIMES = 100; - constexpr int32_t RETRY_INTERVAL = 1 * 1000 * 1000; // retry after 1 second - BlockInteger retry(RETRY_INTERVAL); - while (retry < RETRY_MAX_TIMES) { - auto status = CryptoManager::GetInstance().CheckRootKey(); - if (status == CryptoManager::ErrCode::SUCCESS) { - ZLOGI("root key exist."); - break; - } - if (status == CryptoManager::ErrCode::NOT_EXIST && - CryptoManager::GetInstance().GenerateRootKey() == CryptoManager::ErrCode::SUCCESS) { - ZLOGI("GenerateRootKey success."); - break; - } - ++retry; - ZLOGW("GenerateRootKey failed, retry times:%{public}d.", static_cast(retry)); - } - }); - th.detach(); + executors_->Execute(GetTask(0)); DistributedDB::KvStoreConfig kvStoreConfig{ metaDBDirectory_ }; delegateManager_.SetKvStoreConfig(kvStoreConfig); } +ExecutorPool::Task KvStoreMetaManager::GetTask(uint32_t retry) +{ + return [this, retry] { + auto status = CryptoManager::GetInstance().CheckRootKey(); + if (status == CryptoManager::ErrCode::SUCCESS) { + ZLOGI("root key exist."); + return; + } + if (status == CryptoManager::ErrCode::NOT_EXIST && + CryptoManager::GetInstance().GenerateRootKey() == CryptoManager::ErrCode::SUCCESS) { + ZLOGI("GenerateRootKey success."); + return; + } + ZLOGW("GenerateRootKey failed, retry times:%{public}d.", static_cast(retry)); + if (retry + 1 > RETRY_MAX_TIMES) { + ZLOGE("fail to register subscriber!"); + return; + } + executors_->Schedule(std::chrono::seconds(RETRY_INTERVAL), GetTask(retry + 1)); + }; +} + KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore() { if (metaDelegate_ != nullptr) { @@ -391,5 +394,9 @@ size_t KvStoreMetaManager::GetSyncDataSize(const std::string &deviceId) return metaDelegate->GetSyncDataSize(deviceId); } +void KvStoreMetaManager::BindExecutor(std::shared_ptr executors) +{ + executors_ = executors; +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index 7cea63df6475223a177ac418ad933f26c8dc6b49..9fb69912dea7e1fd23d9d9a9014fb3d98de92435 100644 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -18,9 +18,9 @@ #include #include "app_device_change_listener.h" +#include "executor_pool.h" #include "kv_store_delegate.h" #include "kv_store_delegate_manager.h" -#include "kv_store_task.h" #include "system_ability.h" #include "types.h" @@ -54,6 +54,7 @@ public: void InitDeviceOnline(); void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer); size_t GetSyncDataSize(const std::string &deviceId); + void BindExecutor(std::shared_ptr executors); private: using NbDelegate = std::shared_ptr; NbDelegate GetMetaKvStore(); @@ -72,6 +73,8 @@ private: std::string GetBackupPath() const; + ExecutorPool::Task GetTask(uint32_t retry); + class KvStoreMetaObserver : public DistributedDB::KvStoreObserver { public: virtual ~KvStoreMetaObserver(); @@ -83,6 +86,8 @@ private: void HandleChanges(CHANGE_FLAG flag, const std::list &list); }; + static constexpr int32_t RETRY_MAX_TIMES = 100; + static constexpr int32_t RETRY_INTERVAL = 1; NbDelegate metaDelegate_; std::string metaDBDirectory_; const std::string label_; @@ -90,6 +95,7 @@ private: static MetaDeviceChangeListenerImpl listener_; KvStoreMetaObserver metaObserver_; std::recursive_mutex mutex_; + std::shared_ptr executors_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/security/security.cpp b/services/distributeddataservice/app/src/security/security.cpp index 44845416b699867e7e28600cebc4f4f393cd8455..0ff95061f4be0153fab9eb1258e80207d5febbe9 100644 --- a/services/distributeddataservice/app/src/security/security.cpp +++ b/services/distributeddataservice/app/src/security/security.cpp @@ -161,7 +161,7 @@ Sensitive Security::GetSensitiveByUuid(const std::string &uuid) const { auto it = devicesUdid_.Find(uuid); if (!it.first) { - taskScheduler_.Execute([this, uuid]() { + executors_->Execute([this, uuid]() { auto it = devicesUdid_.Find(uuid); if (it.first) { return; diff --git a/services/distributeddataservice/app/src/security/security.h b/services/distributeddataservice/app/src/security/security.h index debf2d60f1f506036ddba58ace2ddd453351169f..702f2af2c3217aed9c26f9354bc83a6076aa4777 100644 --- a/services/distributeddataservice/app/src/security/security.h +++ b/services/distributeddataservice/app/src/security/security.h @@ -17,8 +17,9 @@ #define OHOS_SECURITY_H #include #include -#include + #include "app_device_change_listener.h" +#include "executor_pool.h" #include "iprocess_system_api_adapter.h" #include "kv_store_delegate_manager.h" #include "sensitive.h" @@ -33,6 +34,7 @@ public: using OnAccessControlledEvent = DistributedDB::OnAccessControlledEvent; using SecurityOption = DistributedDB::SecurityOption; Security(); + explicit Security(std::shared_ptr executors) : executors_(executors) {}; ~Security() override; static bool IsSupportSecurity(); @@ -76,8 +78,8 @@ private: DBStatus GetFileSecurityOption(const std::string &filePath, SecurityOption &option) const; DBStatus GetDirSecurityOption(const std::string &filePath, SecurityOption &option) const; - mutable TaskScheduler taskScheduler_ { "security" }; mutable ConcurrentMap devicesUdid_; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index cf130bb459f3e2f29c65f87b79c828074bc7294d..3d4db8d40f9e03db9f5f769a68348d65501be79d 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -19,7 +19,6 @@ #include #include "account_delegate.h" #include "device_manager_adapter.h" -#include "executor_factory.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" @@ -34,25 +33,32 @@ UpgradeManager &UpgradeManager::GetInstance() return instance; } -void UpgradeManager::Init() +void UpgradeManager::Init(std::shared_ptr executors) { - OHOS::DistributedKv::KvStoreTask retryTask([this]() { - do { - if (InitLocalCapability()) { - break; - } - static constexpr int RETRY_INTERVAL = 500; // millisecond - std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL)); - } while (true); - }); - ExecutorFactory::GetInstance().Execute(std::move(retryTask)); + if (executors_) { + return; + } + executors_ = std::move(executors); + executors_->Execute(GetTask()); +} + +ExecutorPool::Task UpgradeManager::GetTask() +{ + return [this] { + auto succ = InitLocalCapability(); + if (succ) { + return; + } + executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GetTask()); + }; } CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &status) { status = true; - if (capabilityMap_.Contains(deviceId)) { - return capabilityMap_.Find(deviceId).second; + auto index = capabilities_.Find(deviceId); + if (index.first) { + return index.second; } ZLOGI("load capability from meta"); CapMetaData capMetaData; @@ -60,7 +66,7 @@ CapMetaData UpgradeManager::GetCapability(const std::string &deviceId, bool &sta ZLOGD("cap key:%{public}s", Anonymous::Change(std::string(dbKey.begin(), dbKey.end())).c_str()); status = MetaDataManager::GetInstance().LoadMeta(std::string(dbKey.begin(), dbKey.end()), capMetaData); if (status) { - capabilityMap_.Insert(deviceId, capMetaData); + capabilities_.Insert(deviceId, capMetaData); } ZLOGI("device:%{public}s, version:%{public}d, insert:%{public}d", Anonymous::Change(deviceId).c_str(), capMetaData.version, status); @@ -75,7 +81,7 @@ bool UpgradeManager::InitLocalCapability() auto dbKey = CapMetaRow::GetKeyFor(localDeviceId); bool status = MetaDataManager::GetInstance().SaveMeta({ dbKey.begin(), dbKey.end() }, capMetaData); if (status) { - capabilityMap_.Insert(localDeviceId, capMetaData); + capabilities_.Insert(localDeviceId, capMetaData); } ZLOGI("put capability meta data ret %{public}d", status); return status; diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.h b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h index 18c044b2596606554675ecd38576b80441058dba..795178f4a88dfd39a4e0ae7df142bfdd54c35893 100644 --- a/services/distributeddataservice/app/src/session_manager/upgrade_manager.h +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -21,6 +21,7 @@ #include "concurrent_map.h" #include "kvstore_meta_manager.h" #include "metadata/capability_meta_data.h" +#include "executor_pool.h" #include "types.h" namespace OHOS::DistributedData { using DistributedDB::KvStoreNbDelegate; @@ -29,15 +30,18 @@ using OHOS::DistributedKv::KvStoreTuple; class UpgradeManager { public: static UpgradeManager &GetInstance(); - void Init(); + void Init(std::shared_ptr executors); CapMetaData GetCapability(const std::string &deviceId, bool &status); static void SetCompatibleIdentifyByType( KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple, AUTH_GROUP_TYPE groupType); static std::string GetIdentifierByType(int32_t groupType, bool &isSuccess); private: + static constexpr int RETRY_INTERVAL = 500; // milliseconds bool InitLocalCapability(); - ConcurrentMap capabilityMap_ {}; + ExecutorPool::Task GetTask(); + ConcurrentMap capabilities_ {}; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedData #endif // DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H diff --git a/services/distributeddataservice/app/src/task_manager.cpp b/services/distributeddataservice/app/src/task_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1332fc203d99d6a8634ee8e5f2a237c4670cf245 --- /dev/null +++ b/services/distributeddataservice/app/src/task_manager.cpp @@ -0,0 +1,55 @@ +/* +* 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 "task_manager.h" +namespace OHOS::DistributedData { +TaskManager::TaskManager(std::shared_ptr executors) +{ + executors_ = executors; +} + +TaskManager::~TaskManager() +{ + executors_ = nullptr; +} +TaskManager::TaskId TaskManager::Execute(const Task &task) +{ + return executors_->Execute(task); +} +TaskManager::TaskId TaskManager::Execute(const Task &task, Duration delay) +{ + return executors_->Schedule(delay, task); +} +TaskManager::TaskId TaskManager::Schedule(const Task &task, Duration interval) +{ + return executors_->Schedule(task, interval); +} +TaskManager::TaskId TaskManager::Schedule(const Task &task, Duration delay, Duration interval) +{ + return executors_->Schedule(task, delay, interval); +} +TaskManager::TaskId TaskManager::Schedule(const Task &task, Duration delay, Duration interval, uint64_t times) +{ + return executors_->Schedule(task, delay, interval, times); +} +bool TaskManager::Remove(const TaskId &taskId, bool wait) +{ + return executors_->Remove(taskId, wait); +} +TaskManager::TaskId TaskManager::Reset(const TaskId &taskId, Duration interval) +{ + return executors_->Reset(taskId, interval); +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/task_manager.h b/services/distributeddataservice/app/src/task_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..caf1050ef2d9fb184c7e65afbe0bc6fae9a97ef7 --- /dev/null +++ b/services/distributeddataservice/app/src/task_manager.h @@ -0,0 +1,41 @@ +/* +* 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 DISTRIBUTED_DATA_TASK_MANAGER_H +#define DISTRIBUTED_DATA_TASK_MANAGER_H +#include "ithread_pool.h" +#include "executor_pool.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class TaskManager : public DistributedDB::IThreadPool { +public: + using TaskId = uint64_t; + using Task = std::function; + using Duration = std::chrono::steady_clock::duration; + TaskManager() = default; + explicit TaskManager(std::shared_ptr executors); + ~TaskManager() override; + TaskId Execute(const Task &task) override; + TaskId Execute(const Task &task, Duration delay) override; + TaskId Schedule(const Task &task, Duration interval) override; + TaskId Schedule(const Task &task, Duration delay, Duration interval) override; + TaskId Schedule(const Task &task, Duration delay, Duration interval, uint64_t times) override; + bool Remove(const TaskId &taskId, bool wait) override; + TaskId Reset(const TaskId &taskId, Duration interval) override; + +private: + std::shared_ptr executors_ = nullptr; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTED_DATA_TASK_MANAGER_H diff --git a/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/services/distributeddataservice/app/src/uninstaller/BUILD.gn index 030cda89a76abec363b9e40757d5e86b7cc49a00..04daeef74ee9c727d74f853a64e6476bb4b0f640 100755 --- a/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") ohos_static_library("distributeddata_uninstaller_static") { sources = [ @@ -22,23 +23,22 @@ ohos_static_library("distributeddata_uninstaller_static") { include_dirs = [ "../../../adapter/include/account", "../../src", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/kvdb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/permission/include", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", "//third_party/json/single_include", - "//commonlibrary/c_utils/base/include", ] cflags_cc = [ "-fvisibility=hidden" ] deps = [ + "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", ] external_deps = [ @@ -56,4 +56,5 @@ ohos_static_library("distributeddata_uninstaller_static") { ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller.h b/services/distributeddataservice/app/src/uninstaller/uninstaller.h index 244c5139205863a13ee04c6ce5bde9fffde2b167..6047830725884cf776e10a12f3e63185aeb16f71 100644 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller.h +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller.h @@ -20,13 +20,14 @@ #include #include "visibility.h" - +#include "executor_pool.h" namespace OHOS::DistributedKv { class KvStoreDataService; enum Status : int32_t; class Uninstaller { public: - KVSTORE_API virtual Status Init(KvStoreDataService *kvStoreDataService) = 0; + KVSTORE_API virtual Status Init(KvStoreDataService *kvStoreDataService, + std::shared_ptr executors) = 0; KVSTORE_API virtual void UnsubscribeEvent() = 0; KVSTORE_API virtual ~Uninstaller() {} KVSTORE_API static Uninstaller &GetInstance(); diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp index 2ab4cb2246dcb50413469aeaebe92c6a4a41c9e5..81072e469f43c694d6a6ddfd9457c4d238e79833 100644 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp @@ -18,6 +18,7 @@ #include "uninstaller_impl.h" #include #include +#include "bundle_common_event.h" #include "common_event_manager.h" #include "common_event_support.h" #include "device_manager_adapter.h" @@ -46,7 +47,7 @@ void UninstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) Want want = event.GetWant(); std::string action = want.GetAction(); if (action != CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED && - action != CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { + action != OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) { return; } @@ -74,7 +75,7 @@ void UninstallerImpl::UnsubscribeEvent() } } -Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService) +Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService, std::shared_ptr executors) { if (kvStoreDataService == nullptr) { ZLOGW("kvStoreDataService is null."); @@ -82,7 +83,7 @@ Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService) } MatchingSkills matchingSkills; matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); + matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED); CommonEventSubscribeInfo info(matchingSkills); auto callback = [kvStoreDataService](const std::string &bundleName, int32_t userId, int32_t appIndex) { kvStoreDataService->OnUninstall(bundleName, userId, appIndex, IPCSkeleton::GetCallingTokenID()); @@ -107,18 +108,23 @@ Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService) }; auto subscriber = std::make_shared(info, callback); subscriber_ = subscriber; - std::thread th = std::thread([subscriber] { - constexpr int32_t RETRY_TIME = 300; - constexpr int32_t RETRY_INTERVAL = 100 * 1000; - for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIME; ++retry) { - if (CommonEventManager::SubscribeCommonEvent(subscriber)) { - ZLOGI("subscribe uninstall event success"); - break; - } - ZLOGE("subscribe uninstall event fail, try times:%d", static_cast(retry)); - } - }); - th.detach(); + executors_ = executors; + executors_->Execute(GetTask()); return Status::SUCCESS; } +ExecutorPool::Task UninstallerImpl::GetTask() +{ + return [this] { + auto succ = CommonEventManager::SubscribeCommonEvent(subscriber_); + if (succ) { + ZLOGI("subscribe uninstall event success"); + return; + } + ZLOGE("subscribe uninstall event fail, try times:%d", retryTime_); + if (retryTime_++ >= RETRY_TIME) { + return; + } + executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GetTask()); + }; +} } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h index 00dc1f08e1017a8b399b710d8844857499bc6cba..50ec5fe33d53a09470fb5217b4bee88a1c70c9ef 100644 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.h @@ -40,12 +40,17 @@ class UninstallerImpl : public Uninstaller { public: ~UninstallerImpl(); - Status Init(KvStoreDataService *kvStoreDataService) override; + Status Init(KvStoreDataService *kvStoreDataService, std::shared_ptr executors) override; void UnsubscribeEvent() override; private: + static constexpr int32_t RETRY_TIME = 300; + static constexpr int32_t RETRY_INTERVAL = 100; + int32_t retryTime_; + ExecutorPool::Task GetTask(); std::shared_ptr subscriber_ {}; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedKv #endif // DISTRIBUTEDDATAMGR_UNINSTALLER_IMPL_H diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index d081b35ac99da79979be0f5984db1bb35998a4ba..3ce6b41dd8e7d85ef5a82b764a513797a1eb192d 100644 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -49,6 +49,7 @@ config("module_private_config") { "unittest", "../src/uninstaller", "../src/flowctrl_manager", + "../../service/backup/include", "../../../../interfaces/innerkits/distributeddata", "//third_party/json/single_include", ] @@ -58,6 +59,7 @@ config("module_private_config") { [ "//base/powermgr/power_manager/interfaces/innerkits/native/include" ] } ldflags = [ "-Wl,--whole-archive" ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ohos_unittest("KvStoreDataServiceTest") { @@ -74,6 +76,7 @@ ohos_unittest("KvStoreDataServiceTest") { "../src/session_manager/route_head_handler_impl.cpp", "../src/session_manager/session_manager.cpp", "../src/session_manager/upgrade_manager.cpp", + "../src/task_manager.cpp", "unittest/kvstore_data_service_test.cpp", ] @@ -198,64 +201,6 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { part_name = "datamgr_service" } -ohos_unittest("KvStoreUninstallerTest") { - 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", - "../src/kvstore_device_listener.cpp", - "../src/kvstore_meta_manager.cpp", - "../src/security/security.cpp", - "../src/security/sensitive.cpp", - "../src/session_manager/route_head_handler_impl.cpp", - "../src/session_manager/session_manager.cpp", - "../src/session_manager/upgrade_manager.cpp", - "unittest/uninstaller_test.cpp", - ] - - configs = [ ":module_private_config" ] - - deps = [ - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/checker:distributeddata_checker_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager:distributeddata_flowctrl_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/uninstaller:distributeddata_uninstaller_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", - "//third_party/googletest:gtest_main", - ] - - external_deps = [ - "ability_base:base", - "ability_base:want", - "access_token:libaccesstoken_sdk", - "c_utils:utils", - "dataclassification:data_transit_mgr", - "device_auth:deviceauth_sdk", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hitrace_native:libhitracechain", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] - - if (datamgr_service_power) { - external_deps += [ - "battery_manager:batterysrv_client", - "power_manager:powermgr_client", - ] - } - part_name = "datamgr_service" -} - ############################################################################### group("unittest") { @@ -265,7 +210,6 @@ group("unittest") { deps += [ ":KvStoreDataServiceTest", ":KvStoreFlowCtrlManagerTest", - ":KvStoreUninstallerTest", ":SessionManagerTest", ] } diff --git a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp index f016c8cb6c8fe08a54f292ed18d7556af723ef5f..e335ae22bf8c4e434b1e2618fb52b17c93ae2d3b 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp @@ -57,6 +57,7 @@ HWTEST_F(KvStoreDataServiceTest, RegisterClientDeathObserver001, TestSize.Level1 KvStoreDataService kvDataService; Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadCheckers(); + KvStoreMetaManager::GetInstance().BindExecutor(std::make_shared(12, 5)); KvStoreMetaManager::GetInstance().InitMetaParameter(); Status status = kvDataService.RegisterClientDeathObserver(appId, new KvStoreClientDeathObserver()); EXPECT_EQ(status, Status::SUCCESS) << "RegisterClientDeathObserver failed"; diff --git a/services/distributeddataservice/app/test/unittest/session_manager_test.cpp b/services/distributeddataservice/app/test/unittest/session_manager_test.cpp index f2994fdc0ceba0fe1ecd9dffbff1d95afcf997b0..6320bfd6cc9a76cd8b41ce3330a8d242f62c708d 100644 --- a/services/distributeddataservice/app/test/unittest/session_manager_test.cpp +++ b/services/distributeddataservice/app/test/unittest/session_manager_test.cpp @@ -37,12 +37,14 @@ class SessionManagerTest : public testing::Test { public: static void SetUpTestCase() { + auto executors = std::make_shared(12, 5); Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); + KvStoreMetaManager::GetInstance().BindExecutor(executors); KvStoreMetaManager::GetInstance().InitMetaParameter(); KvStoreMetaManager::GetInstance().InitMetaListener(); - DeviceManagerAdapter::GetInstance().Init(); + DeviceManagerAdapter::GetInstance().Init(executors); // init peer device UserMetaData userMetaData; @@ -121,7 +123,7 @@ HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level2) std::vector users; auto recvHandler = RouteHeadHandlerImpl::Create({}); ASSERT_NE(recvHandler, nullptr); - uint32_t parseSize = 0; + uint32_t parseSize = 1; recvHandler->ParseHeadData(data.get(), routeHeadSize, parseSize, users); EXPECT_EQ(routeHeadSize, parseSize); ASSERT_EQ(users.size(), 1); diff --git a/services/distributeddataservice/framework/BUILD.gn b/services/distributeddataservice/framework/BUILD.gn index 20b957baabe16544b0e4b6df21080de8ee297d08..98a05fb2a7ba221ed61decabb569ca7715538a43 100644 --- a/services/distributeddataservice/framework/BUILD.gn +++ b/services/distributeddataservice/framework/BUILD.gn @@ -12,21 +12,31 @@ # limitations under the License. import("//build/ohos.gni") import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") group("build_module") { deps = [ ":distributeddatasvcfwk" ] } -config("module_public_config") { +config("module_config") { visibility = [ ":*" ] include_dirs = [ "include", "//third_party/json/single_include", "//third_party/openssl/include/", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include/", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/include/", + ] +} + +config("module_public_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "//third_party/json/single_include", + "${kv_store_common_path}", ] } @@ -34,6 +44,11 @@ ohos_shared_library("distributeddatasvcfwk") { sources = [ "backuprule/backup_rule_manager.cpp", "checker/checker_manager.cpp", + "cloud/asset_loader.cpp", + "cloud/cloud_db.cpp", + "cloud/cloud_info.cpp", + "cloud/cloud_server.cpp", + "cloud/schema_meta.cpp", "eventcenter/event.cpp", "eventcenter/event_center.cpp", "feature/feature_system.cpp", @@ -50,6 +65,7 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/strategy_meta_data.cpp", "metadata/user_meta_data.cpp", "serializable/serializable.cpp", + "store/auto_cache.cpp", "utils/anonymous.cpp", "utils/block_integer.cpp", "utils/constant.cpp", @@ -60,7 +76,9 @@ ohos_shared_library("distributeddatasvcfwk") { cflags_cc = [ "-fvisibility=hidden" ] - configs = [ ":module_public_config" ] + configs = [ ":module_config" ] + + public_configs = [ ":module_public_config" ] deps = [ "//third_party/openssl:libcrypto_shared" ] @@ -68,4 +86,5 @@ ohos_shared_library("distributeddatasvcfwk") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp b/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp index 2fe059135ada0491a9815c2d12d9638cfca95434..d967ad2f158bbc04c26b186822a613ddd4b7973f 100644 --- a/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp +++ b/services/distributeddataservice/framework/backuprule/backup_rule_manager.cpp @@ -37,11 +37,9 @@ void BackupRuleManager::LoadBackupRules(const std::vector &backupRu void BackupRuleManager::RegisterPlugin(const std::string &backupRule, std::function getter) { - auto it = getters_.Find(backupRule); - if (it.first) { - return; - } - getters_[backupRule] = getter; + getters_.ComputeIfAbsent(backupRule, [&getter](const auto &) mutable { + return std::move(getter); + }); } bool BackupRuleManager::CanBackup() diff --git a/services/distributeddataservice/framework/checker/checker_manager.cpp b/services/distributeddataservice/framework/checker/checker_manager.cpp index b7213f3c229c99b10612b7946d77dd47aa8ee94f..8dbc1bb39650f35574872abef279e293cf6a9e91 100644 --- a/services/distributeddataservice/framework/checker/checker_manager.cpp +++ b/services/distributeddataservice/framework/checker/checker_manager.cpp @@ -42,11 +42,9 @@ void CheckerManager::LoadCheckers(std::vector &checkers) void CheckerManager::RegisterPlugin(const std::string &checker, std::function getter) { - auto it = getters_.Find(checker); - if (it.first) { - return; - } - getters_[checker] = getter; + getters_.ComputeIfAbsent(checker, [&getter](const auto &) mutable { + return std::move(getter); + }); } std::string CheckerManager::GetAppId(const StoreInfo &info) diff --git a/services/distributeddataservice/framework/cloud/asset_loader.cpp b/services/distributeddataservice/framework/cloud/asset_loader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cef89e7db8642219fb9793838a9f64c1eb574e78 --- /dev/null +++ b/services/distributeddataservice/framework/cloud/asset_loader.cpp @@ -0,0 +1,27 @@ +/* + * 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/asset_loader.h" +namespace OHOS::DistributedData { +int32_t AssetLoader::Upload(const std::vector &assets) +{ + return E_NOT_SUPPORT; +} + +int32_t AssetLoader::Download(std::vector &assets) +{ + return E_NOT_SUPPORT; +} +} diff --git a/services/distributeddataservice/framework/cloud/cloud_db.cpp b/services/distributeddataservice/framework/cloud/cloud_db.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd149f8e21c61e173b0d881c490339f047e7f2fc --- /dev/null +++ b/services/distributeddataservice/framework/cloud/cloud_db.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 "cloud/cloud_db.h" +namespace OHOS::DistributedData { +int32_t CloudDB::Execute(const std::string &table, const std::string &sql, const VBucket &extend) +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::BatchInsert(const std::string &table, VBuckets &&values, VBuckets &extends) +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::BatchUpdate(const std::string &table, VBuckets &&values, const VBuckets &extends) +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::BatchDelete(const std::string &table, const VBuckets &extends) +{ + return E_NOT_SUPPORT; +} + +std::shared_ptr CloudDB::Query(const std::string &table, 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; +} + +int32_t CloudDB::Watch(int32_t origin, Watcher &watcher) +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::Unwatch(int32_t origin, Watcher &watcher) +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::Lock() +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::Heartbeat() +{ + return E_NOT_SUPPORT; +} + +int32_t CloudDB::Unlock() +{ + return E_NOT_SUPPORT; +} + +int64_t CloudDB::AliveTime() +{ + return -1; +} + +int32_t CloudDB::Close() +{ + return E_NOT_SUPPORT; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/cloud/cloud_info.cpp b/services/distributeddataservice/framework/cloud/cloud_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3f141ebf041cbf67732bc3eae3692aa6bfa6d01 --- /dev/null +++ b/services/distributeddataservice/framework/cloud/cloud_info.cpp @@ -0,0 +1,104 @@ +/* + * 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/cloud_info.h" +#include "utils/constant.h" + +namespace OHOS::DistributedData { +bool CloudInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(user)], user); + SetValue(node[GET_NAME(id)], id); + SetValue(node[GET_NAME(totalSpace)], totalSpace); + SetValue(node[GET_NAME(remainSpace)], remainSpace); + SetValue(node[GET_NAME(enableCloud)], enableCloud); + SetValue(node[GET_NAME(apps)], apps); + return true; +} + +bool CloudInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(user), user); + GetValue(node, GET_NAME(id), id); + GetValue(node, GET_NAME(totalSpace), totalSpace); + GetValue(node, GET_NAME(remainSpace), remainSpace); + GetValue(node, GET_NAME(enableCloud), enableCloud); + GetValue(node, GET_NAME(apps), apps); + return true; +} + +bool CloudInfo::AppInfo::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(bundleName)], bundleName); + SetValue(node[GET_NAME(appId)], appId); + SetValue(node[GET_NAME(version)], version); + SetValue(node[GET_NAME(cloudSwitch)], cloudSwitch); + return true; +} + +bool CloudInfo::AppInfo::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(bundleName), bundleName); + GetValue(node, GET_NAME(appId), appId); + GetValue(node, GET_NAME(version), version); + GetValue(node, GET_NAME(cloudSwitch), cloudSwitch); + return true; +} + +std::string CloudInfo::GetKey() const +{ + return GetKey(INFO_PREFIX, { std::to_string(user), id }); +} + +std::map CloudInfo::GetSchemaKey() const +{ + std::map keys; + for (const auto &app : apps) { + const auto key = GetKey(SCHEMA_PREFIX, { std::to_string(user), id, app.bundleName }); + keys.insert_or_assign(app.bundleName, key); + } + return keys; +} + +std::string CloudInfo::GetSchemaKey(std::string bundleName) const +{ + return GetKey(SCHEMA_PREFIX, { std::to_string(user), id, bundleName }); +} + +bool CloudInfo::IsValid() const +{ + return !id.empty(); +} + +bool CloudInfo::IsExist(const std::string &bundleName) const +{ + for (const auto &app : apps) { + if (app.bundleName == bundleName) { + return true; + } + } + return false; +} + +std::string CloudInfo::GetPrefix(const std::initializer_list &fields) +{ + return GetKey(INFO_PREFIX, fields).append(Constant::KEY_SEPARATOR); +} + +std::string CloudInfo::GetKey(const std::string &prefix, const std::initializer_list &fields) +{ + return Constant::Join(prefix, Constant::KEY_SEPARATOR, fields); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/cloud_server.cpp b/services/distributeddataservice/framework/cloud/cloud_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17c704a1b3fcf1a9dc109be2dfe503b549dc51c1 --- /dev/null +++ b/services/distributeddataservice/framework/cloud/cloud_server.cpp @@ -0,0 +1,62 @@ +/* + * 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/cloud_server.h" +namespace OHOS::DistributedData { +CloudServer *CloudServer::instance_ = nullptr; +CloudServer *CloudServer::GetInstance() +{ + return instance_; +} + +bool CloudServer::RegisterCloudInstance(CloudServer *instance) +{ + if (instance_ != nullptr) { + return false; + } + instance_ = instance; + return true; +} + +CloudInfo CloudServer::GetServerInfo(int32_t userId) +{ + return CloudInfo(); +} + +SchemaMeta CloudServer::GetAppSchema(int32_t userId, const std::string &bundleName) +{ + return SchemaMeta(); +} + +int32_t CloudServer::Subscribe(int32_t userId, const std::map> &dbs) +{ + return 0; +} + +int32_t CloudServer::Unsubscribe(int32_t userId, const std::map> &dbs) +{ + return 0; +} + +std::shared_ptr CloudServer::ConnectAssetLoader(uint32_t tokenId, const CloudServer::Database &dbMeta) +{ + return nullptr; +} + +std::shared_ptr CloudServer::ConnectCloudDB(uint32_t tokenId, const CloudServer::Database &dbMeta) +{ + return nullptr; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/cloud/schema_meta.cpp b/services/distributeddataservice/framework/cloud/schema_meta.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b6a8cd4b35ecd9d701651340a40aea9b698e867d --- /dev/null +++ b/services/distributeddataservice/framework/cloud/schema_meta.cpp @@ -0,0 +1,93 @@ +/* + * 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/schema_meta.h" +namespace OHOS::DistributedData { +bool SchemaMeta::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(version)], version); + SetValue(node[GET_NAME(databases)], databases); + return true; +} + +bool SchemaMeta::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(version), version); + GetValue(node, GET_NAME(databases), databases); + return true; +} + +bool SchemaMeta::Database::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(name)], name); + SetValue(node[GET_NAME(alias)], alias); + SetValue(node[GET_NAME(tables)], tables); + return true; +} + +bool SchemaMeta::Database::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(name), name); + GetValue(node, GET_NAME(alias), alias); + GetValue(node, GET_NAME(tables), tables); + return true; +} + +bool SchemaMeta::Table::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(name)], name); + SetValue(node[GET_NAME(alias)], alias); + SetValue(node[GET_NAME(fields)], fields); + return true; +} + +bool SchemaMeta::Table::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(name), name); + GetValue(node, GET_NAME(alias), alias); + GetValue(node, GET_NAME(fields), fields); + return true; +} + +bool SchemaMeta::Field::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(colName)], colName); + SetValue(node[GET_NAME(alias)], alias); + SetValue(node[GET_NAME(type)], type); + SetValue(node[GET_NAME(primary)], primary); + SetValue(node[GET_NAME(nullable)], nullable); + return true; +} + +bool SchemaMeta::Field::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(colName), colName); + GetValue(node, GET_NAME(alias), alias); + GetValue(node, GET_NAME(type), type); + GetValue(node, GET_NAME(primary), primary); + GetValue(node, GET_NAME(nullable), nullable); + return true; +} + +SchemaMeta::Database SchemaMeta::GetDataBase(const std::string &storeId) +{ + for (const auto &database : databases) { + if (database.name == storeId) { + return database; + } + } + return {}; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/feature/feature_system.cpp b/services/distributeddataservice/framework/feature/feature_system.cpp index 6013e9cff31355e4c4de3e9c9704606ad7b40444..6bfd3d23bc4499e55ff9ef411d7973ab9a3d27ff 100644 --- a/services/distributeddataservice/framework/feature/feature_system.cpp +++ b/services/distributeddataservice/framework/feature/feature_system.cpp @@ -22,19 +22,33 @@ FeatureSystem &FeatureSystem::GetInstance() return instance; } -int32_t FeatureSystem::RegisterCreator(const std::string &name, Creator creator) +int32_t FeatureSystem::RegisterCreator(const std::string &name, Creator creator, int32_t flag) { - creators_.InsertOrAssign(name, std::move(creator)); - return STUB_SUCCESS; + creators_.InsertOrAssign(name, std::pair{ std::move(creator), flag }); + return E_OK; } FeatureSystem::Creator FeatureSystem::GetCreator(const std::string &name) { - auto it = creators_.Find(name); - if (it.first) { - return it.second; + auto [success, pair] = creators_.Find(name); + if (!success) { + return nullptr; } - return nullptr; + auto [creator, flag] = std::move(pair); + return creator; +} + +std::vector FeatureSystem::GetFeatureName(int32_t flag) +{ + std::vector features; + creators_.ForEach([flag, &features](const std::string &key, auto &pair) -> bool { + auto &[creator, bindFlag] = pair; + if (bindFlag == flag) { + features.push_back(key); + } + return false; + }); + return features; } FeatureSystem::Feature::~Feature() @@ -43,43 +57,48 @@ FeatureSystem::Feature::~Feature() int32_t FeatureSystem::Feature::OnInitialize() { - return STUB_SUCCESS; + return E_OK; +} + +int32_t FeatureSystem::Feature::OnExecutor(std::shared_ptr executors) +{ + return E_OK; } int32_t FeatureSystem::Feature::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::OnUserChange(uint32_t code, const std::string &user, const std::string &account) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::Online(const std::string &device) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::Offline(const std::string &device) { - return STUB_SUCCESS; + return E_OK; } int32_t FeatureSystem::Feature::OnReady(const std::string &device) { - return STUB_SUCCESS; -} + return E_OK; } -} \ No newline at end of file +} // namespace DistributedData +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/framework/include/cloud/asset_loader.h b/services/distributeddataservice/framework/include/cloud/asset_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..0df69eb0a415c5bdb72de379d5658e3c04e75289 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/asset_loader.h @@ -0,0 +1,28 @@ +/* + * 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_CLOUD_ASSET_LOADER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H +#include +#include "store/general_value.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT AssetLoader { +public: + virtual ~AssetLoader() = default; + virtual int32_t Upload(const std::vector &assets); + virtual int32_t Download(std::vector &assets); +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_ASSET_LOADER_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_db.h b/services/distributeddataservice/framework/include/cloud/cloud_db.h new file mode 100644 index 0000000000000000000000000000000000000000..4882d8d7fef83b989eff0ca7774c15ae0b05c170 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/cloud_db.h @@ -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. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_DB_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_DB_H +#include +#include + +#include "store/cursor.h" +#include "store/general_value.h" +#include "store/general_watcher.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT CloudDB { +public: + using Watcher = GeneralWatcher; + using Async = std::function>)>; + using Devices = std::vector; + virtual ~CloudDB() = default; + + virtual int32_t Execute(const std::string &table, const std::string &sql, const VBucket &extend); + + virtual int32_t BatchInsert(const std::string &table, VBuckets &&values, VBuckets &extends); + + virtual int32_t BatchUpdate(const std::string &table, VBuckets &&values, const VBuckets &extends); + + virtual int32_t BatchDelete(const std::string &table, const VBuckets &extends); + + virtual std::shared_ptr Query(const std::string &table, 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); + + virtual int32_t Unwatch(int32_t origin, Watcher &watcher); + + virtual int32_t Lock(); + + virtual int32_t Heartbeat(); + + virtual int32_t Unlock(); + + virtual int64_t AliveTime(); + + virtual int32_t Close(); +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_DB_H diff --git a/services/distributeddataservice/service/data_share/data_share_profile_info.h b/services/distributeddataservice/framework/include/cloud/cloud_info.h similarity index 32% rename from services/distributeddataservice/service/data_share/data_share_profile_info.h rename to services/distributeddataservice/framework/include/cloud/cloud_info.h index 9dac5236f18ff97902976f82cb3639da46e05aa4..5576bca8a4d6b433951e1c3ff6b3eb4000afd72b 100644 --- a/services/distributeddataservice/service/data_share/data_share_profile_info.h +++ b/services/distributeddataservice/framework/include/cloud/cloud_info.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 @@ -13,45 +13,43 @@ * limitations under the License. */ -#ifndef DATA_SHARE_PROFILE_INFO_H -#define DATA_SHARE_PROFILE_INFO_H - -#include "bundle_info.h" -#include "uri_utils.h" +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_INFO_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_INFO_H #include "serializable/serializable.h" -#include "resource_manager.h" +namespace OHOS::DistributedData { +class API_EXPORT CloudInfo final : public Serializable { +public: + struct API_EXPORT AppInfo final : public Serializable { + std::string bundleName = ""; + std::string appId = ""; + uint64_t version = 0; + bool cloudSwitch = false; -namespace OHOS::DataShare { -using namespace OHOS::Global::Resource; -struct Config final : public DistributedData::Serializable { - std::string uri = "*"; - int crossUserMode = 0; - std::string writePermission = ""; - std::string readPermission = ""; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; -}; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + int32_t user = 0; + std::string id = ""; + uint64_t totalSpace = 0; + uint64_t remainSpace = 0; + bool enableCloud = false; + std::vector apps; + + std::string GetKey() const; + std::map GetSchemaKey() const; + std::string GetSchemaKey(std::string bundleName) const; + bool IsValid() const; + bool IsExist(const std::string &bundleName) const; + static std::string GetPrefix(const std::initializer_list &field); -struct ProfileInfo : public DistributedData::Serializable { - std::vector tableConfig; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; -}; - -class DataShareProfileInfo { -public: - DataShareProfileInfo() = default; - bool GetProfileInfoFromExtension(const AppExecFwk::BundleInfo &bundleInfo, - ProfileInfo &profileInfo, bool &isSingleApp); private: - bool GetResProfileByMetadata(const std::vector &metadata, const std::string &resourcePath, - bool isCompressed, std::vector &profileInfos) const; - std::shared_ptr InitResMgr(const std::string &basicString) const; - bool GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, bool isCompressed, - std::vector &profileInfos) const; - std::string ReadProfile(const std::string &resPath) const; - bool IsFileExisted(const std::string &filePath) const; + static constexpr const char *INFO_PREFIX = "CLOUD_INFO"; + static constexpr const char *SCHEMA_PREFIX = "CLOUD_SCHEMA"; + + static std::string GetKey(const std::string &prefix, const std::initializer_list &fields); }; -} // namespace OHOS::DataShare -#endif // DATA_SHARE_PROFILE_INFO_H +} +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_INFO_H diff --git a/services/distributeddataservice/framework/include/cloud/cloud_server.h b/services/distributeddataservice/framework/include/cloud/cloud_server.h new file mode 100644 index 0000000000000000000000000000000000000000..709a0cbcf67c76fe768b1c3f58672ec3a2ce8754 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/cloud_server.h @@ -0,0 +1,41 @@ +/* + * 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_CLOUD_CLOUD_SERVER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_SERVER_H +#include "cloud/asset_loader.h" +#include "cloud/cloud_db.h" +#include "cloud/cloud_info.h" +#include "cloud/schema_meta.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT CloudServer { +public: + using Database = SchemaMeta::Database; + API_EXPORT static CloudServer *GetInstance(); + API_EXPORT static bool RegisterCloudInstance(CloudServer *instance); + + virtual CloudInfo GetServerInfo(int32_t userId); + virtual SchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName); + virtual int32_t Subscribe(int32_t userId, const std::map> &dbs); + virtual int32_t Unsubscribe(int32_t userId, const std::map> &dbs); + virtual std::shared_ptr ConnectAssetLoader(uint32_t tokenId, const Database &dbMeta); + virtual std::shared_ptr ConnectCloudDB(uint32_t tokenId, const Database &dbMeta); + +private: + static CloudServer *instance_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_SERVER_H diff --git a/services/distributeddataservice/framework/include/cloud/schema_meta.h b/services/distributeddataservice/framework/include/cloud/schema_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..188a013262b4877511a88c20d2499811dc9484d4 --- /dev/null +++ b/services/distributeddataservice/framework/include/cloud/schema_meta.h @@ -0,0 +1,61 @@ +/* + * 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_CLOUD_SCHEMA_META_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SCHEMA_META_H +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +class API_EXPORT SchemaMeta final : public Serializable { +public: + static constexpr const char *DELETE_FIELD = "#_deleted"; + static constexpr const char *GID_FIELD = "#_gid"; + static constexpr const char *CREATE_FIELD = "#_createTime"; + static constexpr const char *MODIFY_FIELD = "#_modifyTime"; + static constexpr const char *CURSOR_FIELD = "#_cursor"; + struct API_EXPORT Field final : public Serializable { + std::string colName; + std::string alias; + int32_t type = 0; + bool primary = false; + bool nullable = true; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + + struct API_EXPORT Table final : public Serializable { + std::string name; + std::string alias; + std::vector fields; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + + struct API_EXPORT Database final : public Serializable { + std::string name = ""; + std::string alias; + std::vector tables; + + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + int32_t version = 0; + std::vector databases; + + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + Database GetDataBase(const std::string &storeId); +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SCHEMA_META_H diff --git a/services/distributeddataservice/framework/include/error/general_error.h b/services/distributeddataservice/framework/include/error/general_error.h new file mode 100644 index 0000000000000000000000000000000000000000..8c60a916290acf7404633630ba9c36d17e213aa8 --- /dev/null +++ b/services/distributeddataservice/framework/include/error/general_error.h @@ -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. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_ERROR_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_ERROR_H +namespace OHOS::DistributedData { +enum GeneralError : int32_t { + E_OK = 0, + E_ERROR, + E_BUSY, + E_INVALID_ARGS, + E_NOT_INIT, + E_NOT_SUPPORT, + E_ALREADY_CONSUMED, + E_ALREADY_CLOSED, + E_BUTT, +}; +} +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_ERROR_H diff --git a/services/distributeddataservice/framework/include/feature/feature_system.h b/services/distributeddataservice/framework/include/feature/feature_system.h index 7b4ad3f7974372c5a836ae95998d1bdece4c38d7..8aa732cfd9e78e12367d24cbc0d1665cbed560b7 100644 --- a/services/distributeddataservice/framework/include/feature/feature_system.h +++ b/services/distributeddataservice/framework/include/feature/feature_system.h @@ -15,7 +15,10 @@ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORK_SYSTEM_SYSTEM_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORK_SYSTEM_SYSTEM_H #include + #include "concurrent_map.h" +#include "error/general_error.h" +#include "executor_pool.h" #include "visibility.h" namespace DistributedDB { struct AutoLaunchParam; @@ -25,12 +28,18 @@ class MessageParcel; namespace DistributedData { class API_EXPORT FeatureSystem { public: - static constexpr int32_t STUB_SUCCESS = 0; + using Error = GeneralError; + inline static constexpr int32_t STUB_SUCCESS = Error::E_OK; + enum BindFlag : int32_t { + BIND_LAZY, + BIND_NOW + }; class API_EXPORT Feature { public: virtual ~Feature(); virtual int OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply) = 0; virtual int32_t OnInitialize(); + virtual int32_t OnExecutor(std::shared_ptr executors); virtual int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName); virtual int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); virtual int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); @@ -41,8 +50,9 @@ public: }; using Creator = std::function()>; static FeatureSystem &GetInstance(); - int32_t RegisterCreator(const std::string &name, Creator creator); + int32_t RegisterCreator(const std::string &name, Creator creator, int32_t flag = BIND_LAZY); Creator GetCreator(const std::string &name); + std::vector GetFeatureName(int32_t flag); private: FeatureSystem() = default; @@ -51,7 +61,7 @@ private: FeatureSystem &operator=(const FeatureSystem &) = delete; FeatureSystem &operator=(FeatureSystem &&) = delete; - ConcurrentMap creators_; + ConcurrentMap> creators_; }; } // namespace DistributedData } diff --git a/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/services/distributeddataservice/framework/include/metadata/store_meta_data.h index 2a2fcc5f0fe46666113422dbfdfc371982378141..bb134e354f0670a4b87bd253ba57db7def0af182 100644 --- a/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -22,9 +22,10 @@ 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 = 0x03000003; + static constexpr uint32_t CURRENT_VERSION = 0x03000004; // UID -> uid, deviceAccountId -> userId, userId -> user static constexpr uint32_t FIELD_CHANGED_TAG = 0x03000003; + static constexpr uint32_t UUID_CHANGED_TAG = 0x03000004; uint32_t version = CURRENT_VERSION; bool isAutoSync = false; bool isBackup = false; diff --git a/services/distributeddataservice/framework/include/serializable/serializable.h b/services/distributeddataservice/framework/include/serializable/serializable.h index dc2337c9ece26fea414941c3c9dc44f96ed12530..4b16f8dd3b817fdac6b2e0f8ff14d34f245cbb71 100644 --- a/services/distributeddataservice/framework/include/serializable/serializable.h +++ b/services/distributeddataservice/framework/include/serializable/serializable.h @@ -55,6 +55,7 @@ public: API_EXPORT static bool GetValue(const json &node, const std::string &name, uint32_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, int32_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, int64_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, uint64_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, bool &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, std::vector &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, Serializable &value); @@ -62,6 +63,7 @@ public: API_EXPORT static bool SetValue(json &node, const uint32_t &value); API_EXPORT static bool SetValue(json &node, const int32_t &value); API_EXPORT static bool SetValue(json &node, const int64_t &value); + API_EXPORT static bool SetValue(json &node, const uint64_t &value); API_EXPORT static bool SetValue(json &node, const bool &value); API_EXPORT static bool SetValue(json &node, const std::vector &value); API_EXPORT static bool SetValue(json &node, const Serializable &value); diff --git a/services/distributeddataservice/framework/include/store/auto_cache.h b/services/distributeddataservice/framework/include/store/auto_cache.h new file mode 100644 index 0000000000000000000000000000000000000000..4267a8952c661a6fd2fa0b9c191cf87b0c0289f2 --- /dev/null +++ b/services/distributeddataservice/framework/include/store/auto_cache.h @@ -0,0 +1,86 @@ +/* + * 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_STORE_STORE_AUTO_CACHE_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H +#include +#include +#include +#include "concurrent_map.h" +#include "error/general_error.h" +#include "executor_pool.h" +#include "metadata/store_meta_data.h" +#include "store/general_store.h" +#include "store/general_value.h" +#include "store/general_watcher.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class AutoCache { +public: + using Error = GeneralError; + using Store = std::shared_ptr; + using Watcher = GeneralWatcher; + using Watchers = std::set>; + using Time = std::chrono::steady_clock::time_point; + using Executor = ExecutorPool; + using TaskId = ExecutorPool::TaskId; + using Creator = std::function; + API_EXPORT static AutoCache &GetInstance(); + + API_EXPORT int32_t RegCreator(int32_t type, Creator creator); + + API_EXPORT void Bind(std::shared_ptr executor); + + API_EXPORT Store GetStore(const StoreMetaData &meta, const Watchers &watchers); + + API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); + + API_EXPORT void CloseExcept(const std::set &users); + + API_EXPORT void SetObserver(uint32_t tokenId, const std::string &storeId, const Watchers &watchers); + +private: + AutoCache(); + ~AutoCache(); + void GarbageCollect(bool isForce); + struct Delegate : public GeneralWatcher { + Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user); + ~Delegate(); + operator Store(); + bool operator<(const Time &time) const; + bool Close(); + int32_t GetUser() const; + void SetObservers(const Watchers &watchers); + int32_t OnChange(Origin origin, const std::string &id) override; + int32_t OnChange(Origin origin, const std::string &id, const std::vector &values) override; + + private: + mutable Time time_; + GeneralStore *store_ = nullptr; + Watchers watchers_; + int32_t user_; + std::shared_mutex mutex_; + }; + + static constexpr int64_t INTERVAL = 1; + static constexpr int32_t MAX_CREATOR_NUM = 30; + + std::shared_ptr executor_; + TaskId taskId_ = Executor::INVALID_TASK_ID; + ConcurrentMap> stores_; + Creator creators_[MAX_CREATOR_NUM]; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H diff --git a/services/distributeddataservice/framework/include/store/cursor.h b/services/distributeddataservice/framework/include/store/cursor.h new file mode 100644 index 0000000000000000000000000000000000000000..e588c5fd65e4633671dcc911a283f9a79aed7b41 --- /dev/null +++ b/services/distributeddataservice/framework/include/store/cursor.h @@ -0,0 +1,51 @@ +/* + * 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_STORE_CURSOR_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_CURSOR_H +#include +#include +#include + +#include "store/general_value.h" +namespace OHOS::DistributedData { +class Cursor { +public: + virtual ~Cursor() = default; + + virtual int32_t GetColumnNames(std::vector &names) const = 0; + + virtual int32_t GetColumnName(int32_t col, std::string &name) const = 0; + + virtual int32_t GetColumnType(int32_t col) const = 0; + + virtual int32_t GetCount() const = 0; + + virtual int32_t MoveToFirst() = 0; + + virtual int32_t MoveToNext() = 0; + + virtual int32_t GetEntry(VBucket &entry) = 0; + + virtual int32_t GetRow(VBucket &data) = 0; + + virtual int32_t Get(int32_t col, Value &value) = 0; + + virtual int32_t Get(const std::string &col, Value &value) = 0; + + virtual int32_t Close() = 0; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_CURSOR_H diff --git a/services/distributeddataservice/framework/include/store/general_store.h b/services/distributeddataservice/framework/include/store/general_store.h new file mode 100644 index 0000000000000000000000000000000000000000..56cdcf87abe2841a12b64b9172b339118f62babe --- /dev/null +++ b/services/distributeddataservice/framework/include/store/general_store.h @@ -0,0 +1,57 @@ +/* + * 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_STORE_GENERAL_STORE_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H +#include +#include + +#include "store/cursor.h" +#include "store/general_value.h" +#include "store/general_watcher.h" +namespace OHOS::DistributedData { +class CloudDB; +class GeneralStore { +public: + using Watcher = GeneralWatcher; + using Async = std::function>)>; + using Devices = std::vector; + + virtual ~GeneralStore() = default; + + virtual int32_t Bind(std::shared_ptr cloudDb) = 0; + + virtual int32_t Execute(const std::string &table, const std::string &sql) = 0; + + virtual int32_t BatchInsert(const std::string &table, VBuckets &&values) = 0; + + virtual int32_t BatchUpdate(const std::string &table, const std::string &sql, VBuckets &&values) = 0; + + virtual int32_t Delete(const std::string &table, const std::string &sql, Values &&args) = 0; + + virtual std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) = 0; + + virtual std::shared_ptr Query(const std::string &table, GenQuery &query) = 0; + + virtual int32_t Sync(const Devices &devices, int32_t mode, GenQuery &query, Async async, int32_t wait) = 0; + + virtual int32_t Watch(int32_t origin, Watcher &watcher) = 0; + + virtual int32_t Unwatch(int32_t origin, Watcher &watcher) = 0; + + virtual int32_t Close() = 0; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/services/distributeddataservice/framework/include/store/general_value.h b/services/distributeddataservice/framework/include/store/general_value.h new file mode 100644 index 0000000000000000000000000000000000000000..05d4766d399bfcb496bcc2549786977c9a6a9a65 --- /dev/null +++ b/services/distributeddataservice/framework/include/store/general_value.h @@ -0,0 +1,87 @@ +/* + * 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_STORE_GENERAL_VALUE_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_VALUE_H +#include +#include +#include +#include +#include + +#include "error/general_error.h" +#include "traits.h" +namespace OHOS::DistributedData { +struct Asset { + uint32_t version; + std::string name; + std::string uri; + std::string createTime; + std::string modifyTime; + std::string size; + std::string hash; +}; + +struct GenQuery { + virtual ~GenQuery() = default; + virtual bool IsEqual(uint64_t tid) = 0; + + template + int32_t QueryInterface(T *&query) + { + if (!IsEqual(T::TYPE_ID)) { + return E_INVALID_ARGS; + } + query = static_cast(this); + return E_OK; + }; +}; + +using Assets = std::vector; +using Bytes = std::vector; +using Value = std::variant; +using Values = std::vector; +using VBucket = std::map; +using VBuckets = std::vector; + +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) +{ + return false; +} + +template +bool GetItem(T &&input, O &output) +{ + auto val = Traits::get_if(&input); + if (val != nullptr) { + output = std::move(*val); + return true; + } + return GetItem(std::move(input), output); +} + +template +bool Convert(T &&input, std::variant &output) +{ + return GetItem(std::move(input), output); +} +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_VALUE_H diff --git a/services/distributeddataservice/framework/include/store/general_watcher.h b/services/distributeddataservice/framework/include/store/general_watcher.h new file mode 100644 index 0000000000000000000000000000000000000000..52130eab7005077596a473d6a4e2346895dae712 --- /dev/null +++ b/services/distributeddataservice/framework/include/store/general_watcher.h @@ -0,0 +1,44 @@ +/* + * 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_STORE_GENERAL_WATCHER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_WATCHER_H +#include +#include "store/general_value.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class GeneralWatcher { +public: + enum Origin : int32_t { + ORIGIN_CLOUD, + ORIGIN_LOCAL, + ORIGIN_REMOTE, + ORIGIN_ALL, + ORIGIN_BUTT, + }; + + enum ChangeOp : int32_t { + OP_INSERT, + OP_UPDATE, + OP_DELETE, + OP_BUTT, + }; + + virtual ~GeneralWatcher() = default; + virtual int32_t OnChange(Origin origin, const std::string &id) = 0; + virtual int32_t OnChange(Origin origin, const std::string &id, const std::vector &values) = 0; +}; +} +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_WATCHER_H diff --git a/services/distributeddataservice/framework/serializable/serializable.cpp b/services/distributeddataservice/framework/serializable/serializable.cpp index 9622af95f1f4aa8dcde243b769b5c3c3983e231c..509880a851e84c2958e43ab2078b3d1ab8943266 100644 --- a/services/distributeddataservice/framework/serializable/serializable.cpp +++ b/services/distributeddataservice/framework/serializable/serializable.cpp @@ -103,6 +103,16 @@ bool Serializable::GetValue(const json &node, const std::string &name, int64_t & return true; } +bool Serializable::GetValue(const json &node, const std::string &name, uint64_t &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_number_unsigned()) { + return false; + } + subNode.get_to(value); + return true; +} + bool Serializable::GetValue(const json &node, const std::string &name, bool &value) { auto &subNode = GetSubNode(node, name); @@ -156,6 +166,12 @@ bool Serializable::SetValue(json &node, const int64_t &value) return true; } +bool Serializable::SetValue(json &node, const uint64_t &value) +{ + node = value; + return true; +} + bool Serializable::SetValue(json &node, const bool &value) { node = value; diff --git a/services/distributeddataservice/framework/store/auto_cache.cpp b/services/distributeddataservice/framework/store/auto_cache.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edeb10cd4351959518a6a725befcaae441715890 --- /dev/null +++ b/services/distributeddataservice/framework/store/auto_cache.cpp @@ -0,0 +1,227 @@ +/* + * 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 "AutoCache" +#include "store/auto_cache.h" + +#include "log_print.h" +namespace OHOS::DistributedData { +AutoCache &AutoCache::GetInstance() +{ + static AutoCache cache; + return cache; +} + +int32_t AutoCache::RegCreator(int32_t type, Creator creator) +{ + if (type >= MAX_CREATOR_NUM) { + return E_ERROR; + } + creators_[type] = creator; + return 0; +} + +void AutoCache::Bind(std::shared_ptr executor) +{ + if (executor == nullptr || taskId_ != Executor::INVALID_TASK_ID) { + return; + } + executor_ = executor; + taskId_ = executor_->Schedule(std::bind(&AutoCache::GarbageCollect, this, false), std::chrono::minutes(INTERVAL), + std::chrono::minutes(INTERVAL)); +} + +AutoCache::AutoCache() {} + +AutoCache::~AutoCache() +{ + GarbageCollect(true); + if (executor_ != nullptr) { + executor_->Remove(taskId_, true); + } +} + +AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers &watchers) +{ + Store store; + if (meta.storeType >= MAX_CREATOR_NUM || !creators_[meta.storeType]) { + return store; + } + + stores_.Compute(meta.tokenId, + [this, &meta, &watchers, &store](auto &, std::map &stores) -> bool { + auto it = stores.find(meta.storeId); + if (it != stores.end()) { + it->second.SetObservers(watchers); + store = it->second; + return !stores.empty(); + } + auto *dbStore = creators_[meta.storeType](meta); + if (dbStore == nullptr) { + return !stores.empty(); + } + auto result = stores.emplace(std::piecewise_construct, std::forward_as_tuple(meta.storeId), + std::forward_as_tuple(dbStore, watchers, atoi(meta.user.c_str()))); + store = result.first->second; + return !stores.empty(); + }); + return store; +} + +void AutoCache::CloseStore(uint32_t tokenId, const std::string &storeId) +{ + stores_.ComputeIfPresent(tokenId, [&storeId](auto &key, std::map &delegates) { + auto it = delegates.find(storeId); + if (it != delegates.end()) { + it->second.Close(); + delegates.erase(it); + } + return !delegates.empty(); + }); +} + +void AutoCache::CloseExcept(const std::set &users) +{ + stores_.EraseIf([&users](const auto &tokenId, std::map &delegates) { + if (delegates.empty() || users.count(delegates.begin()->second.GetUser()) != 0) { + return delegates.empty(); + } + + for (auto it = delegates.begin(); it != delegates.end();) { + // if the kv store is BUSY we wait more INTERVAL minutes again + if (!it->second.Close()) { + ++it; + } else { + it = delegates.erase(it); + } + } + return delegates.empty(); + }); +} + +void AutoCache::SetObserver(uint32_t tokenId, const std::string &storeId, const AutoCache::Watchers &watchers) +{ + stores_.ComputeIfPresent(tokenId, [&storeId, &watchers](auto &key, auto &stores) { + ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, storeId.c_str(), watchers.size()); + auto it = stores.find(storeId); + if (it != stores.end()) { + it->second.SetObservers(watchers); + } + return true; + }); +} + +void AutoCache::GarbageCollect(bool isForce) +{ + auto current = std::chrono::steady_clock::now(); + stores_.EraseIf([¤t, isForce](auto &key, std::map &delegates) { + for (auto it = delegates.begin(); it != delegates.end();) { + // if the kv store is BUSY we wait more INTERVAL minutes again + if ((isForce || it->second < current) && it->second.Close()) { + it = delegates.erase(it); + } else { + ++it; + } + } + return delegates.empty(); + }); +} + +AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user) + : store_(delegate), watchers_(watchers), user_(user) +{ + time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + if (store_ != nullptr) { + store_->Watch(ORIGIN_ALL, *this); + } +} + +AutoCache::Delegate::~Delegate() +{ + if (store_ != nullptr) { + store_->Unwatch(ORIGIN_ALL, *this); + store_->Close(); + store_ = nullptr; + } +} + +AutoCache::Delegate::operator Store() +{ + time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + return Store(store_, [](GeneralStore *) {}); +} + +bool AutoCache::Delegate::operator<(const AutoCache::Time &time) const +{ + return time_ < time; +} + +bool AutoCache::Delegate::Close() +{ + std::unique_lock lock(mutex_); + if (store_ != nullptr) { + store_->Unwatch(ORIGIN_ALL, *this); + } + + auto status = store_->Close(); + if (status == Error::E_BUSY) { + return false; + } + store_ = nullptr; + return true; +} + +void AutoCache::Delegate::SetObservers(const AutoCache::Watchers &watchers) +{ + std::unique_lock lock(mutex_); + watchers_ = watchers; +} + +int32_t AutoCache::Delegate::GetUser() const +{ + return user_; +} + +int32_t AutoCache::Delegate::OnChange(Origin origin, const std::string &id) +{ + Watchers watchers; + { + std::unique_lock lock(mutex_); + watchers = watchers_; + } + for (auto watcher : watchers) { + if (watcher == nullptr) { + continue; + } + watcher->OnChange(origin, id); + } + return Error::E_OK; +} + +int32_t AutoCache::Delegate::OnChange(Origin origin, const std::string &id, const std::vector &values) +{ + Watchers watchers; + { + std::unique_lock lock(mutex_); + watchers = watchers_; + } + for (auto watcher : watchers) { + if (watcher == nullptr) { + continue; + } + watcher->OnChange(origin, id, values); + } + return Error::E_OK; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/test/BUILD.gn b/services/distributeddataservice/framework/test/BUILD.gn index 006e0bd0682a50ffd189890279305c2d620da2b8..1e2ccfa56878f30e7d2cf6cbccd3e45f39836add 100644 --- a/services/distributeddataservice/framework/test/BUILD.gn +++ b/services/distributeddataservice/framework/test/BUILD.gn @@ -24,6 +24,7 @@ config("module_private_config") { "../../service/bootstrap/include/", ] ldflags = [ "-Wl,--whole-archive" ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } ohos_unittest("CheckerManagerTest") { diff --git a/services/distributeddataservice/framework/test/serializable_test.cpp b/services/distributeddataservice/framework/test/serializable_test.cpp index 55364fd9c0b861995a77f39e5c0fd02f0f242001..95c0154b447b485fbe04080e012199b58ce0f6ce 100644 --- a/services/distributeddataservice/framework/test/serializable_test.cpp +++ b/services/distributeddataservice/framework/test/serializable_test.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #define LOG_TAG "SerializableTest" +#include #include "log_print.h" #include "serializable/serializable.h" #include "gtest/gtest.h" @@ -112,7 +113,7 @@ public: */ HWTEST_F(SerializableTest, GetNormalVal, TestSize.Level2) { - ZLOGI("SerializableSuite GetVal begin."); + ZLOGI("SerializableSuite GetNormalVal begin."); Normal normal; normal.name = "normal"; normal.count = -1; @@ -135,9 +136,9 @@ HWTEST_F(SerializableTest, GetNormalVal, TestSize.Level2) */ HWTEST_F(SerializableTest, DeleteSerializable, TestSize.Level2) { - ZLOGI("SerializableSuite GetVal begin."); - NormalEx *normalEx = new NormalEx(); - delete normalEx; + ZLOGI("SerializableSuite DeleteSerializable begin."); + ASSERT_FALSE(std::is_destructible::value); + ASSERT_TRUE(std::is_destructible::value); } /** @@ -149,7 +150,7 @@ HWTEST_F(SerializableTest, DeleteSerializable, TestSize.Level2) */ HWTEST_F(SerializableTest, GetMutilVal, TestSize.Level2) { - ZLOGI("SerializableSuite GetVal begin."); + ZLOGI("SerializableSuite GetMutilVal begin."); NormalEx normalEx; normalEx.normals = {Normal()}; normalEx.name = "normalEx"; diff --git a/services/distributeddataservice/service/BUILD.gn b/services/distributeddataservice/service/BUILD.gn index 6adf404a342fb6b0818da7143688be7629148b4c..b6360e93f6999b9b8469ac88793f6630d44c1707 100644 --- a/services/distributeddataservice/service/BUILD.gn +++ b/services/distributeddataservice/service/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") import("//build/ohos_var.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") group("build_module") { deps = [ ":distributeddatasvc" ] @@ -23,7 +24,10 @@ config("module_public_config") { "bootstrap/include", "config/include", "crypto/include", - "datashare", + "data_share", + "data_share/strategies", + "data_share/common", + "data_share/data", "directory/include", "kvdb", "matrix/include", @@ -34,25 +38,22 @@ config("module_public_config") { "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "//foundation/distributeddatamgr/data_share/frameworks/native/common/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/common/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/consumer/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include/", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/relational", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", - "//foundation/bundlemanager/bundle_framework/interfaces/inner_api/appexecfwk_base/include", + "${datashare_path}/frameworks/native/common/include", + "${datashare_path}/interfaces/inner_api/common/include", + "${datashare_path}/interfaces/inner_api/consumer/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", ] } ohos_shared_library("distributeddatasvc") { include_dirs = [ "../../../../data_object/frameworks/innerkitsimpl/include", - "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include/distributeddb", + "${kv_store_distributeddb_path}", ] sources = [ "backup/src/backup_manager.cpp", @@ -66,14 +67,35 @@ ohos_shared_library("distributeddatasvc") { "config/src/model/network_config.cpp", "config/src/model/protocol_config.cpp", "crypto/src/crypto_manager.cpp", - "data_share/bundle_mgr_proxy.cpp", - "data_share/data_share_profile_info.cpp", + "data_share/common/bundle_mgr_proxy.cpp", + "data_share/common/db_delegate.cpp", + "data_share/common/div_strategy.cpp", + "data_share/common/kv_delegate.cpp", + "data_share/common/rdb_delegate.cpp", + "data_share/common/seq_strategy.cpp", + "data_share/common/uri_utils.cpp", + "data_share/data_share_obs_proxy.cpp", "data_share/data_share_service_impl.cpp", "data_share/data_share_service_stub.cpp", "data_share/data_share_types_util.cpp", - "data_share/permission_proxy.cpp", - "data_share/rdb_adaptor.cpp", - "data_share/uri_utils.cpp", + "data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp", + "data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp", + "data_share/strategies/delete_strategy.cpp", + "data_share/strategies/general/check_is_data_proxy_strategy.cpp", + "data_share/strategies/general/check_is_single_app_strategy.cpp", + "data_share/strategies/general/connect_extension_strategy.cpp", + "data_share/strategies/general/empty_strategy.cpp", + "data_share/strategies/general/load_config_common_strategy.cpp", + "data_share/strategies/general/load_config_data_info_strategy.cpp", + "data_share/strategies/general/load_config_from_bundle_info_strategy.cpp", + "data_share/strategies/general/permission_strategy.cpp", + "data_share/strategies/general/process_single_app_user_cross_strategy.cpp", + "data_share/strategies/get_data_strategy.cpp", + "data_share/strategies/insert_strategy.cpp", + "data_share/strategies/publish_strategy.cpp", + "data_share/strategies/query_strategy.cpp", + "data_share/strategies/subscribe_strategy.cpp", + "data_share/strategies/update_strategy.cpp", "directory/src/directory_manager.cpp", "kvdb/auth_delegate.cpp", "kvdb/executor_factory.cpp", @@ -109,15 +131,16 @@ ohos_shared_library("distributeddatasvc") { configs = [ ":module_public_config" ] deps = [ + "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", ] external_deps = [ + "ability_base:want", "ability_base:zuri", + "ability_runtime:ability_manager", "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "bundle_framework:appexecfwk_base", @@ -129,7 +152,9 @@ ohos_shared_library("distributeddatasvc") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "kv_store:distributeddata_inner", "relational_store:native_rdb", + "relational_store:rdb_bms_adapter", "relational_store:rdb_data_share_adapter", "resource_management:global_resmgr", "samgr:samgr_proxy", @@ -137,4 +162,5 @@ ohos_shared_library("distributeddatasvc") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/services/distributeddataservice/service/backup/include/backup_manager.h b/services/distributeddataservice/service/backup/include/backup_manager.h index 43060215036ce0ee431f9655c56d82473d838218..1d4c38e5d13079cc1c7002320b1fd0837a11ec91 100644 --- a/services/distributeddataservice/service/backup/include/backup_manager.h +++ b/services/distributeddataservice/service/backup/include/backup_manager.h @@ -16,9 +16,9 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_BACKUP_BACKUP_MANAGER_H #define OHOS_DISTRIBUTED_DATA_SERVICES_BACKUP_BACKUP_MANAGER_H -#include "task_scheduler.h" -#include "metadata/store_meta_data.h" +#include "executor_pool.h" #include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" #include "types.h" namespace OHOS::DistributedData { class BackupManager { @@ -37,7 +37,7 @@ public: }; static BackupManager &GetInstance(); void Init(); - void BackSchedule(); + void BackSchedule(std::shared_ptr executors); void SetBackupParam(const BackupParam &backupParam); void RegisterExporter(int32_t type, Exporter exporter); bool GetPassWord(const StoreMetaData &meta, std::vector &password); @@ -64,7 +64,7 @@ private: int64_t backupSuccessTime_ = 0; int64_t backupNumber_ = 0; int64_t startNum_ = 0; - TaskScheduler scheduler_ { "backup" }; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_BACKUP_BACKUP_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/backup/src/backup_manager.cpp b/services/distributeddataservice/service/backup/src/backup_manager.cpp index 66164fff781f5bdf2789c6dcbbf01200edb611b8..5c52cbd735a4d0c3591d586aea8f2c5198580c2a 100644 --- a/services/distributeddataservice/service/backup/src/backup_manager.cpp +++ b/services/distributeddataservice/service/backup/src/backup_manager.cpp @@ -90,35 +90,40 @@ void BackupManager::RegisterExporter(int32_t type, Exporter exporter) } } -void BackupManager::BackSchedule() +void BackupManager::BackSchedule(std::shared_ptr executors) { + if (!executors_) { + executors_ = std::move(executors); + } std::chrono::duration delay(schedularDelay_); std::chrono::duration internal(schedularInternal_); ZLOGI("BackupManager Schedule start."); - scheduler_.Every(delay, internal, [this]() { - if (!CanBackup()) { - return; - } + executors_->Schedule( + [this]() { + if (!CanBackup()) { + return; + } - ZLOGI("start automatic backup."); - std::vector metas; - MetaDataManager::GetInstance().LoadMeta( - StoreMetaData::GetPrefix({DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid}), metas); + ZLOGI("start automatic backup."); + std::vector metas; + MetaDataManager::GetInstance().LoadMeta( + StoreMetaData::GetPrefix({ DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), metas); - int64_t end = std::min(startNum_ + backupNumber_, static_cast(metas.size())); - for (int64_t i = startNum_; i < end; startNum_++, i++) { - auto &meta = metas[i]; - if (!meta.isBackup || meta.isDirty) { - continue; + int64_t end = std::min(startNum_ + backupNumber_, static_cast(metas.size())); + for (int64_t i = startNum_; i < end; startNum_++, i++) { + auto &meta = metas[i]; + if (!meta.isBackup || meta.isDirty) { + continue; + } + DoBackup(meta); } - DoBackup(meta); - } - if (startNum_ >= static_cast(metas.size())) { - startNum_ = 0; - } - sync(); - backupSuccessTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - }); + if (startNum_ >= static_cast(metas.size())) { + startNum_ = 0; + } + sync(); + backupSuccessTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + }, + delay, internal); } void BackupManager::DoBackup(const StoreMetaData &meta) diff --git a/services/distributeddataservice/service/bootstrap/include/bootstrap.h b/services/distributeddataservice/service/bootstrap/include/bootstrap.h index a86984385c8b716eaec4af52f1936f4fde9e24d6..c23012366fe8c45b414a2e89dc63a477c5fc9be4 100644 --- a/services/distributeddataservice/service/bootstrap/include/bootstrap.h +++ b/services/distributeddataservice/service/bootstrap/include/bootstrap.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_BOOTSTRAP_BOOTSTRAP_H #define OHOS_DISTRIBUTED_DATA_SERVICES_BOOTSTRAP_BOOTSTRAP_H #include +#include "executor_pool.h" #include "visibility.h" namespace OHOS { namespace DistributedData { @@ -28,7 +29,7 @@ public: API_EXPORT void LoadCheckers(); API_EXPORT void LoadNetworks(); API_EXPORT void LoadDirectory(); - API_EXPORT void LoadBackup(); + API_EXPORT void LoadBackup(std::shared_ptr executors); private: static constexpr const char *DEFAULT_LABEL = "distributeddata"; static constexpr const char *DEFAULT_META = "service_meta"; diff --git a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 7d39b94f828c12b853f1815677093c2867c583c7..6cdd57ab27b92b1b04055b99e303713c68c66183 100644 --- a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -58,7 +58,6 @@ void Bootstrap::LoadComponents() if (comp.lib.empty()) { continue; } - // no need to close the component, so we don't keep the handles auto handle = dlopen(comp.lib.c_str(), RTLD_LAZY); if (handle == nullptr) { @@ -95,7 +94,7 @@ void Bootstrap::LoadCheckers() } } -void Bootstrap::LoadBackup() +void Bootstrap::LoadBackup(std::shared_ptr executors) { auto *backupRules = ConfigFactory::GetInstance().GetBackupConfig(); if (backupRules == nullptr) { @@ -107,7 +106,7 @@ void Bootstrap::LoadBackup() backupRules->schedularInternal, backupRules->backupInternal, backupRules->backupNumber}; BackupManager::GetInstance().SetBackupParam(backupParam); BackupManager::GetInstance().Init(); - BackupManager::GetInstance().BackSchedule(); + BackupManager::GetInstance().BackSchedule(std::move(executors)); } void Bootstrap::LoadNetworks() diff --git a/services/distributeddataservice/service/data_share/bundle_mgr_proxy.cpp b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp similarity index 61% rename from services/distributeddataservice/service/data_share/bundle_mgr_proxy.cpp rename to services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp index ef7683a26ec2cc495b336717c15668aa44b78db1..4519382ff675af40311b1fa947a96d18ad8b053a 100644 --- a/services/distributeddataservice/service/data_share/bundle_mgr_proxy.cpp +++ b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp @@ -1,78 +1,91 @@ -/* - * 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. - */ -#define LOG_TAG "BundleMgrProxy" -#include "bundle_mgr_proxy.h" - -#include "account/account_delegate.h" -#include "if_system_ability_manager.h" -#include "iservice_registry.h" -#include "log_print.h" -#include "system_ability_definition.h" - -namespace OHOS::DataShare { -sptr BundleMgrProxy::GetBundleMgrProxy() -{ - std::lock_guard lock(mutex_); - if (proxy_ != nullptr) { - return proxy_; - } - sptr systemAbilityManager = - SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (systemAbilityManager == nullptr) { - ZLOGE("Failed to get system ability mgr."); - return nullptr; - } - - sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); - if (remoteObject == nullptr) { - ZLOGE("Failed to get bundle manager proxy."); - return nullptr; - } - sptr deathRecipient = new (std::nothrow) - BundleMgrProxy::ServiceDeathRecipient(this); - if (deathRecipient == nullptr) { - return nullptr; - } - remoteObject->AddDeathRecipient(deathRecipient); - proxy_ = iface_cast(remoteObject); - ZLOGD("Get bundle manager proxy success."); - return proxy_; -} - -bool BundleMgrProxy::GetBundleInfoFromBMS( - const std::string &bundleName, uint32_t tokenId, AppExecFwk::BundleInfo &bundleInfo) -{ - auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); - auto bmsClient = GetBundleMgrProxy(); - if (!bmsClient) { - ZLOGE("GetBundleMgrProxy is nullptr!"); - return false; - } - bool ret = bmsClient->GetBundleInfo( - bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); - if (!ret) { - ZLOGE("GetBundleInfo failed!"); - return false; - } - return true; -} - -void BundleMgrProxy::OnProxyDied() -{ - std::lock_guard lock(mutex_); - proxy_ = nullptr; - ZLOGE("DIED."); -} +/* + * 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 "BundleMgrProxy" +#include "bundle_mgr_proxy.h" + +#include "account/account_delegate.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "log_print.h" +#include "system_ability_definition.h" + +namespace OHOS::DataShare { +sptr BundleMgrProxy::GetBundleMgrProxy() +{ + std::lock_guard lock(mutex_); + if (proxy_ != nullptr) { + return iface_cast(proxy_); + } + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + ZLOGE("Failed to get system ability mgr."); + return nullptr; + } + + proxy_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (proxy_ == nullptr) { + ZLOGE("Failed to get bundle manager proxy."); + return nullptr; + } + deathRecipient_ = new (std::nothrow)BundleMgrProxy::ServiceDeathRecipient(weak_from_this()); + if (deathRecipient_ == nullptr) { + ZLOGE("deathRecipient alloc failed."); + return nullptr; + } + proxy_->AddDeathRecipient(deathRecipient_); + return iface_cast(proxy_); +} + +bool BundleMgrProxy::GetBundleInfoFromBMS( + const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo) +{ + auto bmsClient = GetBundleMgrProxy(); + if (bmsClient == nullptr) { + ZLOGE("GetBundleMgrProxy is nullptr!"); + return false; + } + bool ret = bmsClient->GetBundleInfo( + bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); + if (!ret) { + ZLOGE("GetBundleInfo failed!bundleName is %{public}s, userId is %{public}d", bundleName.c_str(), userId); + return false; + } + return true; +} + +void BundleMgrProxy::OnProxyDied() +{ + std::lock_guard lock(mutex_); + if (proxy_ != nullptr) { + proxy_->RemoveDeathRecipient(deathRecipient_); + } + proxy_ = nullptr; +} + +BundleMgrProxy::~BundleMgrProxy() +{ + std::lock_guard lock(mutex_); + if (proxy_ != nullptr) { + proxy_->RemoveDeathRecipient(deathRecipient_); + } +} + +std::shared_ptr BundleMgrProxy::GetInstance() +{ + static std::shared_ptr proxy(new BundleMgrProxy()); + return proxy; +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/bundle_mgr_proxy.h b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h similarity index 61% rename from services/distributeddataservice/service/data_share/bundle_mgr_proxy.h rename to services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h index d36cb95008b65e9d7dfc8483451eedd913d743f7..e66197a1e9b2f40d8edee15303a94111bc1382a0 100644 --- a/services/distributeddataservice/service/data_share/bundle_mgr_proxy.h +++ b/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h @@ -1,46 +1,52 @@ -/* - * 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 DATASHARESERVICE_BUNDLEMGR_PROXY_H -#define DATASHARESERVICE_BUNDLEMGR_PROXY_H - -#include - -#include "bundlemgr/bundle_mgr_proxy.h" -namespace OHOS::DataShare { -class BundleMgrProxy { -public: - bool GetBundleInfoFromBMS(const std::string &bundleName, uint32_t tokenId, AppExecFwk::BundleInfo &bundleInfo); - -private: - class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { - public: - explicit ServiceDeathRecipient(BundleMgrProxy* owner) : owner_(owner) {} - void OnRemoteDied(const wptr &object) override - { - if (owner_ != nullptr) { - owner_->OnProxyDied(); - } - } - private: - BundleMgrProxy* owner_; - }; - sptr GetBundleMgrProxy(); - void OnProxyDied(); - std::mutex mutex_; - sptr proxy_; -}; -} // namespace OHOS::DataShare -#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H +/* + * 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 DATASHARESERVICE_BUNDLEMGR_PROXY_H +#define DATASHARESERVICE_BUNDLEMGR_PROXY_H + +#include +#include +#include "bundlemgr/bundle_mgr_proxy.h" +namespace OHOS::DataShare { +class BundleMgrProxy final : public std::enable_shared_from_this { +public: + ~BundleMgrProxy(); + static std::shared_ptr GetInstance(); + bool GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo); + +private: + BundleMgrProxy() = default; + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit ServiceDeathRecipient(std::weak_ptr owner) : owner_(owner) {} + void OnRemoteDied(const wptr &object) override + { + auto owner = owner_.lock(); + if (owner != nullptr) { + owner->OnProxyDied(); + } + } + + private: + std::weak_ptr owner_; + }; + sptr GetBundleMgrProxy(); + void OnProxyDied(); + std::mutex mutex_; + sptr proxy_; + sptr deathRecipient_; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/services/distributeddataservice/service/data_share/common/callback_impl.h b/services/distributeddataservice/service/data_share/common/callback_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..072379099a943957520b1f265e414e6cdab62cb9 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/callback_impl.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 DATASHARESERVICE_CALLBACK_IMPL_H +#define DATASHARESERVICE_CALLBACK_IMPL_H + +#include "ability_connect_callback_stub.h" +#include "ability_manager_client.h" +#include "block_data.h" + +namespace OHOS::DataShare { +class CallbackImpl : public AAFwk::AbilityConnectionStub { +public: + CallbackImpl(BlockData &data) : data_(data) {} + void OnAbilityConnectDone( + const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override + { + bool result = true; + data_.SetValue(result); + } + void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override + { + bool result = false; + data_.SetValue(result); + } + +private: + BlockData &data_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/common/context.h b/services/distributeddataservice/service/data_share/common/context.h new file mode 100644 index 0000000000000000000000000000000000000000..d506e4b1651146aec3236c1d766b1afad0e25a59 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/context.h @@ -0,0 +1,56 @@ +/* + * 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 DATASHARESERVICE_CONTEXT_H +#define DATASHARESERVICE_CONTEXT_H + +#include +#include +#include +#include + +#include "bundle_info.h" + +namespace OHOS::DataShare { +enum AccessSystemMode : uint8_t { + UNDEFINED, + USER_SHARED_MODE, + USER_SINGLE_MODE, + MAX, +}; +class Context { +public: + explicit Context() {} + explicit Context(const std::string &uri) : uri(uri) {} + virtual ~Context() = default; + std::string uri; + int32_t currentUserId = -1; + std::string permission; + uint32_t callerTokenId = -1; + std::string callerBundleName; + std::string calledBundleName; + std::string calledModuleName; + std::string calledStoreName; + std::string calledTableName; + std::string calledSourceDir; // the dir of db + int version = -1; + int errCode = -1; + bool isRead = false; + AccessSystemMode accessSystemMode = AccessSystemMode::UNDEFINED; + OHOS::AppExecFwk::BundleInfo bundleInfo; + std::string type = "rdb"; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/services/distributeddataservice/service/data_share/common/db_delegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97e451bc2ce054bdd42f98b6d281b04897bcfb3b --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -0,0 +1,69 @@ +/* + * 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 "DBAdaptor" +#include "db_delegate.h" + +#include "kv_delegate.h" +#include "rdb_delegate.h" +namespace OHOS::DataShare { +std::shared_ptr DBDelegate::Create(const std::string &dir, int version) +{ + return std::make_shared(dir, version); +} + +std::shared_ptr KvDBDelegate::GetInstance(bool reInit, const std::string &dir) +{ + static std::shared_ptr delegate = nullptr; + static std::mutex mutex; + std::lock_guard lock(mutex); + if (delegate == nullptr || reInit) { + delegate = std::make_shared(dir); + } + return delegate; +} + +bool KvData::Marshal(DistributedData::Serializable::json &node) const +{ + auto ret = SetValue(node, *GetId()); + if (HasVersion()) { + ret &= SetValue(node, GetVersion()); + } + return ret & SetValue(node, GetValue()); +} + +bool Id::Marshal(DistributedData::Serializable::json &node) const +{ + return SetValue(node[GET_NAME(_id)], _id); +} + +bool Id::Unmarshal(const DistributedData::Serializable::json &node) +{ + return GetValue(node, GET_NAME(_id), _id); +} + +Id::Id(const std::string &id) : _id(id) {} + +VersionData::VersionData(int version) : version(version) {} + +bool VersionData::Unmarshal(const DistributedData::Serializable::json &node) +{ + return GetValue(node, GET_NAME(version), version); +} + +bool VersionData::Marshal(DistributedData::Serializable::json &node) const +{ + return SetValue(node[GET_NAME(version)], version); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/db_delegate.h b/services/distributeddataservice/service/data_share/common/db_delegate.h new file mode 100644 index 0000000000000000000000000000000000000000..e6ec2721c78b4a8972bdf5420d7b9cfd7ef2409f --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -0,0 +1,101 @@ +/* + * 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 DATASHARESERVICE_DB_DELEGATE_H +#define DATASHARESERVICE_DB_DELEGATE_H + +#include + +#include "concurrent_map.h" +#include "datashare_predicates.h" +#include "datashare_result_set.h" +#include "datashare_values_bucket.h" +#include "result_set.h" +#include "serializable/serializable.h" + +namespace OHOS::DataShare { +class DBDelegate { +public: + static std::shared_ptr Create(const std::string &dir, int version); + 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; + virtual int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) = 0; + virtual std::shared_ptr Query(const std::string &tableName, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; + virtual std::shared_ptr Query( + const std::string &sql, const std::vector &selectionArgs = std::vector()) = 0; + virtual int ExecuteSql(const std::string &sql) = 0; +}; + +struct RdbStoreContext { + RdbStoreContext(const std::string &dir, int version) : dir(dir), version(version) {} + std::string dir; + int version; +}; + +struct Id final: public DistributedData::Serializable { + explicit Id(const std::string &id); + ~Id() = default; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + +private: + std::string _id; +}; + +class VersionData : public DistributedData::Serializable { +public: + explicit VersionData(int version); + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + VersionData &operator=(int inputVersion) + { + version = inputVersion; + return *this; + }; + operator int() + { + return version; + }; + +private: + int version; +}; + +struct KvData : public DistributedData::Serializable { + virtual std::shared_ptr GetId() const = 0; + virtual bool HasVersion() const = 0; + virtual VersionData GetVersion() const = 0; + virtual const Serializable &GetValue() const = 0; + bool Marshal(json &node) const override; +}; + +class KvDBDelegate { +public: + static constexpr const char *TEMPLATE_TABLE = "template_"; + static constexpr const char *DATA_TABLE = "data_"; + static std::shared_ptr GetInstance(bool reInit = false, const std::string &dir = ""); + virtual ~KvDBDelegate() = default; + virtual int32_t Upsert(const std::string &collectionName, const KvData &value) = 0; + virtual int32_t DeleteById(const std::string &collectionName, const Id &id) = 0; + virtual int32_t Get(const std::string &collectionName, const Id &id, std::string &value) = 0; + virtual int32_t Get(const std::string &collectionName, const std::string &filter, const std::string &projection, + std::string &result) = 0; + virtual int32_t GetBatch(const std::string &collectionName, const std::string &filter, + const std::string &projection, std::vector &result) = 0; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_DB_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/common/div_strategy.cpp b/services/distributeddataservice/service/data_share/common/div_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afec15a031b11f25c09270a5f6ff5dd63fa49721 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/div_strategy.cpp @@ -0,0 +1,28 @@ +/* + * 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 "DivStrategy" +#include "div_strategy.h" + +#include "log_print.h" +namespace OHOS::DataShare { +bool DivStrategy::operator()(std::shared_ptr context) +{ + if (check_ == nullptr || trueAction_ == nullptr || falseAction_ == nullptr) { + ZLOGE("wrong strategy"); + return false; + } + return (*check_)(context) ? (*trueAction_)(context) : (*falseAction_)(context); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/div_strategy.h b/services/distributeddataservice/service/data_share/common/div_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..5989a3ddacb41c2d079248c752ba3565e6ab7388 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/div_strategy.h @@ -0,0 +1,38 @@ +/* + * 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 DATASHARESERVICE_DIV_STRAGETY_H +#define DATASHARESERVICE_DIV_STRAGETY_H + +#include "context.h" +#include "strategy.h" + +namespace OHOS::DataShare { +class DivStrategy : public Strategy { +public: + DivStrategy(std::shared_ptr check, + std::shared_ptr trueAction, std::shared_ptr falseAction) + : check_(check), trueAction_(trueAction), falseAction_(falseAction) + { + } + bool operator()(std::shared_ptr context) override; + +private: + std::shared_ptr check_; + std::shared_ptr trueAction_; + std::shared_ptr falseAction_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.cpp b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cbbb3fcd6ee97b82ae3552dece03f1ca4e84264d --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.cpp @@ -0,0 +1,106 @@ +/* + * 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 "KvAdaptor" +#include "kv_delegate.h" +#include "datashare_errno.h" +#include "directory_manager.h" +#include "ipc_skeleton.h" +#include "log_print.h" + +namespace OHOS::DataShare { +int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string &filter, const std::string &value) +{ + return E_OK; +} + +int64_t KvDelegate::Delete(const std::string &collectionName, const std::string &filter) +{ + return E_OK; +} + +bool KvDelegate::Init() +{ + if (isInitDone_) { + return true; + } + isInitDone_ = true; + return true; +} + +int32_t KvDelegate::Upsert(const std::string &collectionName, const KvData &value) +{ + std::string id = DistributedData::Serializable::Marshall(*value.GetId()); + if (value.HasVersion() && value.GetVersion() != 0) { + int version = -1; + if (GetVersion(collectionName, id, version)) { + if (value.GetVersion() <= version) { + ZLOGE("GetVersion failed,%{public}s id %{private}s %{public}d %{public}d", collectionName.c_str(), + id.c_str(), static_cast(value.GetVersion()), version); + return E_VERSION_NOT_NEWER; + } + } + } + return Upsert(collectionName, id, DistributedData::Serializable::Marshall(value.GetValue())); +} + +int32_t KvDelegate::DeleteById(const std::string &collectionName, const Id &id) +{ + return Delete(collectionName, DistributedData::Serializable::Marshall(id)); +} + +int32_t KvDelegate::Get(const std::string &collectionName, const Id &id, std::string &value) +{ + std::string filter = DistributedData::Serializable::Marshall(id); + if (Get(collectionName, filter, "{}", value) != E_OK) { + ZLOGE("Get failed, %{public}s %{public}s", collectionName.c_str(), filter.c_str()); + return false; + } + return true; +} + +bool KvDelegate::GetVersion(const std::string &collectionName, const std::string &filter, int &version) +{ + std::string value; + if (Get(collectionName, filter, "{}", value) != E_OK) { + ZLOGE("Get failed, %{public}s %{public}s", collectionName.c_str(), filter.c_str()); + return false; + } + VersionData data(-1); + if (!DistributedData::Serializable::Unmarshall(value, data)) { + ZLOGE("Unmarshall failed,data %{public}s", value.c_str()); + return false; + } + version = data; + return true; +} + +int32_t KvDelegate::Get( + const std::string &collectionName, const std::string &filter, const std::string &projection, std::string &result) +{ + return E_OK; +} + +void KvDelegate::Flush() +{ +} + +int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::string &filter, + const std::string &projection, std::vector &result) +{ + return E_OK; +} + +KvDelegate::KvDelegate(const std::string &path) : path_(path) {} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/common/kv_delegate.h b/services/distributeddataservice/service/data_share/common/kv_delegate.h new file mode 100644 index 0000000000000000000000000000000000000000..fe11133734d8e6102a2b7619fb18e04302d6908b --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/kv_delegate.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_KV_DELEGATE_H +#define DATASHARESERVICE_KV_DELEGATE_H + +#include +#include + +#include "db_delegate.h" + +namespace OHOS::DataShare { +class KvDelegate final : public KvDBDelegate { +public: + explicit KvDelegate(const std::string &path); + int32_t Upsert(const std::string &collectionName, const KvData &value) override; + int32_t DeleteById(const std::string &collectionName, const Id &id) override; + int32_t Get(const std::string &collectionName, const Id &id, std::string &value) override; + + int32_t Get(const std::string &collectionName, const std::string &filter, const std::string &projection, + std::string &result) override; + int32_t GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, + std::vector &result) override; + +private: + bool Init(); + bool GetVersion(const std::string &collectionName, const std::string &filter, int &version); + int64_t Upsert(const std::string &collectionName, const std::string &filter, const std::string &value); + int64_t Delete(const std::string &collectionName, const std::string &filter); + void Flush(); + std::string path_; + bool isInitDone_ = false; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_KV_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/rdb_adaptor.cpp b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp similarity index 42% rename from services/distributeddataservice/service/data_share/rdb_adaptor.cpp rename to services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index 9f4589fba014fc5107edb992f3381128e293be30..a5e6ad2177a3481882e1555589af42d5c718678b 100644 --- a/services/distributeddataservice/service/data_share/rdb_adaptor.cpp +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -1,143 +1,134 @@ -/* - * 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. - */ -#define LOG_TAG "RdbAdaptor" -#include "rdb_adaptor.h" - -#include "log_print.h" -#include "permission_proxy.h" -#include "rdb_utils.h" -#include "rdb_errno.h" - -namespace OHOS::DataShare { -int32_t RdbAdaptor::Insert(const UriInfo &uriInfo, const DataShareValuesBucket &valuesBucket, int32_t userId) -{ - DistributedData::StoreMetaData metaData; - if (!PermissionProxy::QueryMetaData(uriInfo.bundleName, uriInfo.storeName, metaData, userId)) { - return -1; - } - int errCode = E_OK; - RdbDelegate delegate(metaData, errCode); - return delegate.Insert(uriInfo.tableName, valuesBucket); -} -int32_t RdbAdaptor::Update(const UriInfo &uriInfo, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket, int32_t userId) -{ - DistributedData::StoreMetaData metaData; - if (!PermissionProxy::QueryMetaData(uriInfo.bundleName, uriInfo.storeName, metaData, userId)) { - return -1; - } - int errCode = E_OK; - RdbDelegate delegate(metaData, errCode); - return delegate.Update(uriInfo.tableName, predicate, valuesBucket); -} -int32_t RdbAdaptor::Delete(const UriInfo &uriInfo, const DataSharePredicates &predicate, int32_t userId) -{ - DistributedData::StoreMetaData metaData; - if (!PermissionProxy::QueryMetaData(uriInfo.bundleName, uriInfo.storeName, metaData, userId)) { - return -1; - } - int errCode = E_OK; - RdbDelegate delegate(metaData, errCode); - return delegate.Delete(uriInfo.tableName, predicate); -} -std::shared_ptr RdbAdaptor::Query(const UriInfo &uriInfo, const DataSharePredicates &predicates, - const std::vector &columns, int32_t userId, int &errCode) -{ - DistributedData::StoreMetaData metaData; - if (!PermissionProxy::QueryMetaData(uriInfo.bundleName, uriInfo.storeName, metaData, userId)) { - errCode = E_DB_NOT_EXIST; - return nullptr; - } - RdbDelegate delegate(metaData, errCode); - return delegate.Query(uriInfo.tableName, predicates, columns); -} - -RdbDelegate::RdbDelegate(const StoreMetaData &meta, int &errCode) -{ - RdbStoreConfig config(meta.dataDir); - config.SetCreateNecessary(false); - DefaultOpenCallback callback; - store_ = RdbHelper::GetRdbStore(config, meta.version, callback, errCode); - if (errCode != E_OK) { - ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, meta.storeId.c_str()); - } -} - -RdbDelegate::~RdbDelegate() -{ - ZLOGI("destroy"); -} - -int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) -{ - if (store_ == nullptr) { - ZLOGE("store is null"); - return 0; - } - int64_t rowId = 0; - ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); - int ret = store_->Insert(rowId, tableName, bucket); - if (ret != E_OK) { - ZLOGE("Insert failed %{public}d", ret); - } - return rowId; -} -int64_t RdbDelegate::Update(const std::string &tableName, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) -{ - if (store_ == nullptr) { - ZLOGE("store is null"); - return 0; - } - int rowId = 0; - ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); - RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); - int ret = store_->Update(rowId, bucket, predicates); - if (ret != E_OK) { - ZLOGE("Insert failed %{public}d", ret); - } - return rowId; -} -int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredicates &predicate) -{ - if (store_ == nullptr) { - ZLOGE("store is null"); - return 0; - } - int rowId = 0; - RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); - int ret = store_->Delete(rowId, predicates); - if (ret != E_OK) { - ZLOGE("Insert failed %{public}d", ret); - } - return rowId; -} -std::shared_ptr RdbDelegate::Query(const std::string &tableName, - const DataSharePredicates &predicates, const std::vector &columns) -{ - if (store_ == nullptr) { - ZLOGE("store is null"); - return nullptr; - } - RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); - std::shared_ptr resultSet = store_->QueryByStep(rdbPredicates, columns); - if (resultSet == nullptr) { - ZLOGE("Query failed"); - return nullptr; - } - auto bridge = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); - return std::make_shared(bridge); -} +/* + * 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 "RdbAdaptor" +#include "rdb_delegate.h" + +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +constexpr static int32_t MAX_RESULTSET_COUNT = 16; +std::atomic RdbDelegate::resultSetCount = 0; +RdbDelegate::RdbDelegate(const std::string &dir, int version) +{ + RdbStoreConfig config(dir); + config.SetCreateNecessary(false); + DefaultOpenCallback callback; + store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_); + if (errCode_ != E_OK) { + ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_, + DistributedData::Anonymous::Change(dir).c_str()); + } +} + +int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return 0; + } + int64_t rowId = 0; + ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); + int ret = store_->Insert(rowId, tableName, bucket); + if (ret != E_OK) { + ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret); + } + return rowId; +} +int64_t RdbDelegate::Update( + const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return 0; + } + int changeCount = 0; + ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); + RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); + int ret = store_->Update(changeCount, bucket, predicates); + if (ret != E_OK) { + ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret); + } + return changeCount; +} +int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredicates &predicate) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return 0; + } + int changeCount = 0; + RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); + int ret = store_->Delete(changeCount, predicates); + if (ret != E_OK) { + ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret); + } + return changeCount; +} +std::shared_ptr RdbDelegate::Query( + const std::string &tableName, const DataSharePredicates &predicates, + const std::vector &columns, int &errCode) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + errCode = errCode_; + return nullptr; + } + int count = resultSetCount.fetch_add(1); + ZLOGD("start query %{public}d", count); + if (count > MAX_RESULTSET_COUNT) { + ZLOGE("resultSetCount is full"); + resultSetCount--; + return nullptr; + } + RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); + std::shared_ptr resultSet = store_->QueryByStep(rdbPredicates, columns); + if (resultSet == nullptr) { + ZLOGE("Query failed %{public}s", tableName.c_str()); + resultSetCount--; + return nullptr; + } + auto bridge = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); + return std::shared_ptr(new DataShareResultSet(bridge), [](auto p) { + ZLOGD("release resultset"); + resultSetCount--; + delete p; + }); +} + +std::shared_ptr RdbDelegate::Query( + const std::string &sql, const std::vector &selectionArgs) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return nullptr; + } + std::shared_ptr resultSet = store_->QueryByStep(sql, selectionArgs); + if (resultSet == nullptr) { + ZLOGE("Query failed %{private}s", sql.c_str()); + return nullptr; + } + return nullptr; +} + +int RdbDelegate::ExecuteSql(const std::string &sql) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return -1; + } + return store_->ExecuteSql(sql); +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/rdb_adaptor.h b/services/distributeddataservice/service/data_share/common/rdb_delegate.h similarity index 52% rename from services/distributeddataservice/service/data_share/rdb_adaptor.h rename to services/distributeddataservice/service/data_share/common/rdb_delegate.h index fccfc607fed33672c04ae3486ead224d0bd791cf..b8fdcd9243664c21db37af4ee18dc489a94b46ae 100644 --- a/services/distributeddataservice/service/data_share/rdb_adaptor.h +++ b/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -1,70 +1,62 @@ -/* - * 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 DATASHARESERVICE_RDB_ADAPTOR_H -#define DATASHARESERVICE_RDB_ADAPTOR_H - -#include -#include - -#include "concurrent_map.h" -#include "datashare_predicates.h" -#include "datashare_result_set.h" -#include "datashare_values_bucket.h" -#include "metadata/store_meta_data.h" -#include "rdb_errno.h" -#include "rdb_helper.h" -#include "rdb_store.h" -#include "uri_utils.h" - -namespace OHOS::DataShare { -using StoreMetaData = OHOS::DistributedData::StoreMetaData; -using namespace OHOS::NativeRdb; -class RdbDelegate { -public: - RdbDelegate(const StoreMetaData &data, int &errCode); - virtual ~RdbDelegate(); - int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket); - int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket); - int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate); - std::shared_ptr Query(const std::string &tableName, const DataSharePredicates &predicates, - const std::vector &columns); - -private: - std::shared_ptr store_; -}; -class RdbAdaptor { -public: - static int32_t Insert(const UriInfo &uriInfo, const DataShareValuesBucket &valuesBucket, int32_t userId); - static int32_t Update(const UriInfo &uriInfo, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket, int32_t userId); - static int32_t Delete(const UriInfo &uriInfo, const DataSharePredicates &predicate, int32_t userId); - static std::shared_ptr Query(const UriInfo &uriInfo, const DataSharePredicates &predicates, - const std::vector &columns, int32_t userId, int &errCode); -}; -class DefaultOpenCallback : public RdbOpenCallback { -public: - int OnCreate(RdbStore &rdbStore) override - { - return E_OK; - } - int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override - { - return E_OK; - } -}; -} // namespace OHOS::DataShare -#endif // DATASHARESERVICE_RDB_ADAPTOR_H +/* + * 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 DATASHARESERVICE_RDB_DELEGATE_H +#define DATASHARESERVICE_RDB_DELEGATE_H + +#include +#include + +#include "concurrent_map.h" +#include "db_delegate.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_store.h" +#include "uri_utils.h" +#include "rdb_utils.h" + +namespace OHOS::DataShare { +using namespace OHOS::NativeRdb; +class RdbDelegate final : public DBDelegate { +public: + explicit RdbDelegate(const std::string &dir, int version); + 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; + int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) override; + std::shared_ptr Query(const std::string &tableName, const DataSharePredicates &predicates, + const std::vector &columns, int &errCode) override; + std::shared_ptr Query( + const std::string &sql, const std::vector &selectionArgs) override; + int ExecuteSql(const std::string &sql) override; + +private: + static std::atomic resultSetCount; + std::shared_ptr store_; + int errCode_; +}; +class DefaultOpenCallback : public RdbOpenCallback { +public: + int OnCreate(RdbStore &rdbStore) override + { + return E_OK; + } + int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override + { + return E_OK; + } +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_RDB_DELEGATE_H diff --git a/services/distributeddataservice/service/data_share/common/seq_strategy.cpp b/services/distributeddataservice/service/data_share/common/seq_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62700398eba0db2c1cde8705202175c3f46d1e2b --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/seq_strategy.cpp @@ -0,0 +1,44 @@ +/* + * 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 "SeqStrategy" +#include "seq_strategy.h" + +#include "log_print.h" +namespace OHOS::DataShare { +bool SeqStrategy::operator()(std::shared_ptr context) +{ + for (auto &action : actions_) { + if (!(*action)(context)) { + return false; + } + } + return true; +} +bool SeqStrategy::Init(std::initializer_list strategies) +{ + for (auto &item: strategies) { + if (item == nullptr) { + actions_.clear(); + return false; + } + actions_.emplace_back(item); + } + return true; +} +bool SeqStrategy::IsEmpty() +{ + return actions_.empty(); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/app/test/unittest/uninstaller_test.cpp b/services/distributeddataservice/service/data_share/common/seq_strategy.h similarity index 42% rename from services/distributeddataservice/app/test/unittest/uninstaller_test.cpp rename to services/distributeddataservice/service/data_share/common/seq_strategy.h index dedd386d560e1b1c1075fe060fa627268ffb879e..95bf655d1b5a2fbdb179b3d5965657302a1d1fcd 100644 --- a/services/distributeddataservice/app/test/unittest/uninstaller_test.cpp +++ b/services/distributeddataservice/service/data_share/common/seq_strategy.h @@ -1,53 +1,35 @@ -/* - * 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. - */ - -#include -#include "uninstaller/uninstaller.h" - -using namespace testing::ext; -using namespace OHOS::DistributedKv; - -class UninstallerTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -void UninstallerTest::SetUpTestCase(void) -{} - -void UninstallerTest::TearDownTestCase(void) -{} - -void UninstallerTest::SetUp(void) -{} - -void UninstallerTest::TearDown(void) -{} - -/** - * @tc.name: Test001 - * @tc.desc: test get uninstaller instance. - * @tc.type: FUNC - * @tc.require: SR000DOGUN AR000DPSE9 - * @tc.author: hongbo - */ -HWTEST_F(UninstallerTest, Test001, TestSize.Level0) -{ - auto &unin = Uninstaller::GetInstance(); - unin.Init(nullptr); -} +/* + * 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 DATASHARESERVICE_SEQ_STRAGETY_H +#define DATASHARESERVICE_SEQ_STRAGETY_H + +#include + +#include "context.h" +#include "strategy.h" + +namespace OHOS::DataShare { +class SeqStrategy : public Strategy { +public: + bool IsEmpty(); + bool Init(std::initializer_list strategies); + bool operator()(std::shared_ptr context) override; + +private: + std::list> actions_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/common/strategy.h b/services/distributeddataservice/service/data_share/common/strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..0f603e8be420d00963a69364a5c985f0470f22c6 --- /dev/null +++ b/services/distributeddataservice/service/data_share/common/strategy.h @@ -0,0 +1,41 @@ +/* + * 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 DATASHARESERVICE_STRAGETY_H +#define DATASHARESERVICE_STRAGETY_H + +#include +#include + +#include "context.h" + +namespace OHOS::DataShare { +class Strategy { +public: + Strategy() = default; + Strategy(const Strategy &) = delete; + Strategy(const Strategy &&) = delete; + Strategy &operator=(const Strategy &) = delete; + Strategy &operator=(const Strategy &&) = delete; + virtual ~Strategy() + { + }; + virtual bool operator()(std::shared_ptr context) + { + return false; + }; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/uri_utils.cpp b/services/distributeddataservice/service/data_share/common/uri_utils.cpp similarity index 40% rename from services/distributeddataservice/service/data_share/uri_utils.cpp rename to services/distributeddataservice/service/data_share/common/uri_utils.cpp index a4e8a82ad28ab17342355dc669abf80ce12be157..5d6a4ffb134aa9ffa4bcfcd068f927d9047bf4f8 100644 --- a/services/distributeddataservice/service/data_share/uri_utils.cpp +++ b/services/distributeddataservice/service/data_share/common/uri_utils.cpp @@ -1,66 +1,77 @@ -/* - * 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. - */ -#define LOG_TAG "URIUtils" - -#include "uri_utils.h" - -#include "log_print.h" -#include "string_ex.h" -#include "uri.h" - -namespace OHOS::DataShare { -bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo, bool tableNameEmpty) -{ - Uri uriTemp(uri); - std::vector splitUri; - SplitStr(uriTemp.GetPath(), "/", splitUri); - if (!IsValidPath(splitUri, tableNameEmpty)) { - ZLOGE("Invalid uri: %{public}s", uri.c_str()); - return false; - } - - uriInfo.bundleName = splitUri[URI_INDEX_BUNLDENAME]; - uriInfo.moduleName = splitUri[URI_INDEX_MODULENAME]; - uriInfo.storeName = splitUri[URI_INDEX_STORENAME]; - if (splitUri.size() > URI_INDEX_MIN) { - uriInfo.tableName = splitUri[URI_INDEX_TABLENAME]; - } - return true; -} - -bool URIUtils::IsValidPath(const std::vector &splitUri, bool tableNameEmpty) -{ - if (splitUri.size() < URI_INDEX_MIN) { - return false; - } - if (splitUri[URI_INDEX_BUNLDENAME].empty() || splitUri[URI_INDEX_MODULENAME].empty() || - splitUri[URI_INDEX_STORENAME].empty()) { - ZLOGE("Uri has empty field!"); - return false; - } - - if (!tableNameEmpty) { - if (splitUri.size() < URI_INDEX_MAX) { - ZLOGE("Uri need contains tableName"); - return false; - } - if (splitUri[URI_INDEX_TABLENAME].empty()) { - ZLOGE("Uri tableName can't be empty!"); - return false; - } - } - return true; -} +/* + * 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 "URIUtils" + +#include "uri_utils.h" + +#include "log_print.h" +#include "string_ex.h" +#include "uri.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo) +{ + Uri uriTemp(uri); + std::vector splitUri; + SplitStr(uriTemp.GetPath(), "/", splitUri); + if (splitUri.size() < PARAM_SIZE) { + ZLOGE("Invalid uri: %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + return false; + } + + if (splitUri[BUNDLE_NAME].empty() || splitUri[MODULE_NAME].empty() || + splitUri[STORE_NAME].empty() || splitUri[TABLE_NAME].empty()) { + ZLOGE("Uri has empty field! bundleName: %{public}s uri: %{public}s", splitUri[BUNDLE_NAME].c_str(), + DistributedData::Anonymous::Change(uri).c_str()); + return false; + } + + uriInfo.bundleName = splitUri[BUNDLE_NAME]; + uriInfo.moduleName = splitUri[MODULE_NAME]; + uriInfo.storeName = splitUri[STORE_NAME]; + uriInfo.tableName = splitUri[TABLE_NAME]; + return true; +} + +bool URIUtils::IsDataProxyURI(const std::string &uri) +{ + return uri.compare(0, DATA_PROXY_SCHEMA_LEN, URIUtils::DATA_PROXY_SCHEMA) == 0; +} + +bool URIUtils::GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName) +{ + Uri uriTemp(uri); + if (!uriTemp.GetAuthority().empty()) { + bundleName = uriTemp.GetAuthority(); + } + return true; +} + +bool URIUtils::GetUserIdFromProxyURI(const std::string &uri, int32_t &user) +{ + Uri uriTemp(uri); + std::vector splitUri; + SplitStr(uriTemp.GetQuery(), "=", splitUri); + for (auto iter = splitUri.begin(); iter < splitUri.end(); iter++) { + if (*iter == "user" && iter + 1 < splitUri.end()) { + const char *value = (iter + 1)->c_str(); + user = atoi(value); + return true; + } + } + return false; +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/uri_utils.h b/services/distributeddataservice/service/data_share/common/uri_utils.h similarity index 60% rename from services/distributeddataservice/service/data_share/uri_utils.h rename to services/distributeddataservice/service/data_share/common/uri_utils.h index 99a2e1b6404aeee62dc6f6b30a8f8ae6108e4117..0bf62d160229a79abfaaddf3700ca4b32407eeff 100644 --- a/services/distributeddataservice/service/data_share/uri_utils.h +++ b/services/distributeddataservice/service/data_share/common/uri_utils.h @@ -1,49 +1,48 @@ -/* - * 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 DATASHARESERVICE_URI_UTILS_H -#define DATASHARESERVICE_URI_UTILS_H - -#include -#include - -namespace OHOS::DataShare { -struct UriInfo { - std::string bundleName; - std::string moduleName; - std::string storeName; - std::string tableName; - - void SetTableName(const std::string &name) - { - tableName = name; - } -}; - -class URIUtils { -public: - static bool GetInfoFromURI(const std::string &uri, UriInfo &uriInfo, bool tableNameEmpty = false); - -private: - static bool IsValidPath(const std::vector &splitUri, bool tableNameEmpty); - static constexpr size_t URI_INDEX_BUNLDENAME = 0; - static constexpr size_t URI_INDEX_MODULENAME = 1; - static constexpr size_t URI_INDEX_STORENAME = 2; - static constexpr size_t URI_INDEX_TABLENAME = 3; - static constexpr size_t URI_INDEX_MIN = 3; - static constexpr size_t URI_INDEX_MAX = 4; -}; -} // namespace OHOS::DataShare -#endif // DATASHARESERVICE_URI_UTILS_H +/* + * 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 DATASHARESERVICE_URI_UTILS_H +#define DATASHARESERVICE_URI_UTILS_H + +#include +namespace OHOS::DataShare { +struct UriInfo { + std::string bundleName; + std::string moduleName; + std::string storeName; + std::string tableName; +}; + +class URIUtils { +public: + static bool GetInfoFromURI(const std::string &uri, UriInfo &uriInfo); + static bool GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName); + static bool GetUserIdFromProxyURI(const std::string &uri, int32_t &user); + static bool IsDataProxyURI(const std::string &uri); + static constexpr const char *DATA_SHARE_SCHEMA = "datashare:///";; + static constexpr const char DATA_PROXY_SCHEMA[] = "datashareproxy://"; + static constexpr int DATA_PROXY_SCHEMA_LEN = sizeof(DATA_PROXY_SCHEMA); + +private: + enum PATH_PARAM : int32_t { + BUNDLE_NAME = 0, + MODULE_NAME, + STORE_NAME, + TABLE_NAME, + PARAM_SIZE + }; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_URI_UTILS_H diff --git a/services/distributeddataservice/service/data_share/data_proxy_observer.h b/services/distributeddataservice/service/data_share/data_proxy_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..10a71f531ed0943322df524d2a3c77454b895d29 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data_proxy_observer.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 DATA_PROXY_OBSERVER_H +#define DATA_PROXY_OBSERVER_H + +#include +#include "datashare_template.h" + +namespace OHOS { +namespace DataShare { +class IDataProxyRdbObserver : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataProxyRdbObserver"); + virtual void OnChangeFromRdb(RdbChangeNode &changeNode) = 0; +}; + +class IDataProxyPublishedDataObserver : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataProxyPublishedDataObserver"); + virtual void OnChangeFromPublishedData(PublishedDataChangeNode &changeNode) = 0; +}; +} // namespace DataShare +} // namespace OHOS +#endif // DATA_PROXY_OBSERVER_H diff --git a/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp b/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f754e57edc23d6d3ce477e09718d973d4848e362 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp @@ -0,0 +1,71 @@ +/* + * 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 "ObserverProxy" +#include "data_share_obs_proxy.h" + +#include "itypes_util.h" +#include "log_print.h" + +namespace OHOS { +namespace DataShare { +static constexpr int REQUEST_CODE = 0; +void RdbObserverProxy::OnChangeFromRdb(RdbChangeNode &changeNode) +{ + MessageParcel parcel; + if (!parcel.WriteInterfaceToken(RdbObserverProxy::GetDescriptor())) { + return; + } + + if (!ITypesUtil::Marshal(parcel, changeNode)) { + ZLOGE("failed to WriteParcelable changeNode "); + return; + } + + MessageParcel reply; + MessageOption option; + int32_t result = Remote()->SendRequest(REQUEST_CODE, parcel, reply, option); + if (result == ERR_NONE) { + ZLOGI("SendRequest ok, retval is %{public}d", reply.ReadInt32()); + } else { + ZLOGE("SendRequest error, result=%{public}d", result); + return; + } +} + +void PublishedDataObserverProxy::OnChangeFromPublishedData(PublishedDataChangeNode &changeNode) +{ + MessageParcel parcel; + if (!parcel.WriteInterfaceToken(PublishedDataObserverProxy::GetDescriptor())) { + return; + } + + if (!ITypesUtil::Marshal(parcel, changeNode)) { + ZLOGE("failed to WriteParcelable changeNode "); + return; + } + + MessageParcel reply; + MessageOption option; + int32_t result = Remote()->SendRequest(REQUEST_CODE, parcel, reply, option); + if (result == ERR_NONE) { + ZLOGI("SendRequest ok, retval is %{public}d", reply.ReadInt32()); + } else { + ZLOGE("SendRequest error, result=%{public}d", result); + return; + } +} +} // namespace DataShare +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data_share_obs_proxy.h b/services/distributeddataservice/service/data_share/data_share_obs_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..b54e0b0ceda78e00da752a9ddf9f1588f82765b5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/data_share_obs_proxy.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 DATASHARESERVICE_DATA_SHARE_OBS_PROXY_H +#define DATASHARESERVICE_DATA_SHARE_OBS_PROXY_H + +#include "iremote_proxy.h" +#include "data_proxy_observer.h" +#include "datashare_template.h" + +namespace OHOS::DataShare { +class RdbObserverProxy : public IRemoteProxy { +public: + explicit RdbObserverProxy(const sptr& remote) : IRemoteProxy(remote) {} + virtual ~RdbObserverProxy() {} + void OnChangeFromRdb(RdbChangeNode &changeNode) override; + +private: + static inline BrokerDelegator delegator_; +}; + +class PublishedDataObserverProxy : public IRemoteProxy { +public: + explicit PublishedDataObserverProxy(const sptr& remote) + : IRemoteProxy(remote) {} + virtual ~PublishedDataObserverProxy() {} + void OnChangeFromPublishedData(PublishedDataChangeNode &changeNode) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::DataShare +#endif // DATA_SHARE_OBS_PROXY_H diff --git a/services/distributeddataservice/service/data_share/data_share_profile_info.cpp b/services/distributeddataservice/service/data_share/data_share_profile_info.cpp deleted file mode 100644 index 329b9499858320981a904531decca0e44b47a89e..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/data_share_profile_info.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2022-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 "DataShareProfileInfo" -#include "data_share_profile_info.h" - -#include -#include -#include -#include - -#include "bundle_info.h" -#include "log_print.h" - -namespace OHOS::DataShare { -namespace { - constexpr const char* DATA_SHARE_PROFILE_META = "ohos.extension.dataShare"; - constexpr const char* PROFILE_FILE_PREFIX = "$profile:"; - const size_t PROFILE_PREFIX_LEN = strlen(PROFILE_FILE_PREFIX); -} -bool Config::Marshal(json &node) const -{ - SetValue(node[GET_NAME(uri)], uri); - SetValue(node[GET_NAME(crossUserMode)], crossUserMode); - SetValue(node[GET_NAME(readPermission)], readPermission); - SetValue(node[GET_NAME(writePermission)], writePermission); - return true; -} - -bool Config::Unmarshal(const json &node) -{ - bool ret = true; - ret = GetValue(node, GET_NAME(uri), uri) && ret; - GetValue(node, GET_NAME(crossUserMode), crossUserMode); - GetValue(node, GET_NAME(readPermission), readPermission); - GetValue(node, GET_NAME(writePermission), writePermission); - return ret; -} - -bool ProfileInfo::Marshal(json &node) const -{ - SetValue(node[GET_NAME(tableConfig)], tableConfig); - return true; -} - -bool ProfileInfo::Unmarshal(const json &node) -{ - bool ret = true; - ret = GetValue(node, GET_NAME(tableConfig), tableConfig) && ret; - return ret; -} - -bool DataShareProfileInfo::GetProfileInfoFromExtension(const AppExecFwk::BundleInfo &bundleInfo, - ProfileInfo &profileInfo, bool &isSingleApp) -{ - isSingleApp = bundleInfo.singleton; - // non singleApp don't need get profileInfo - if (!isSingleApp) { - return true; - } - - for (auto &item : bundleInfo.extensionInfos) { - if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - std::vector infos; - bool isCompressed = !item.hapPath.empty(); - std::string resourcePath = isCompressed ? item.hapPath : item.resourcePath; - if (!GetResProfileByMetadata(item.metadata, resourcePath, isCompressed, infos) || infos.empty()) { - ZLOGE("failed, bundleName is %{public}s, resourcePath is %{public}s, metadata.size is %{public}zu," - "infos.size is %{public}zu", bundleInfo.name.c_str(), resourcePath.c_str(), item.metadata.size(), - infos.size()); - return false; - } - return profileInfo.Unmarshall(infos[0]); - } - } - ZLOGE("not find datashare extension, bundleName is %{public}s", bundleInfo.name.c_str()); - return false; -} - -bool DataShareProfileInfo::GetResProfileByMetadata(const std::vector &metadata, - const std::string &resourcePath, bool isCompressed, std::vector &profileInfos) const -{ - if (metadata.empty() || resourcePath.empty()) { - return false; - } - std::shared_ptr resMgr = InitResMgr(resourcePath); - if (resMgr == nullptr) { - return false; - } - - for (auto &meta : metadata) { - if (meta.name.compare(DATA_SHARE_PROFILE_META) == 0) { - return GetResFromResMgr(meta.resource, *resMgr, isCompressed, profileInfos); - } - } - return false; -} - -std::shared_ptr DataShareProfileInfo::InitResMgr(const std::string &resourcePath) const -{ - std::shared_ptr resMgr(CreateResourceManager()); - if (resMgr == nullptr) { - return nullptr; - } - - std::unique_ptr resConfig(CreateResConfig()); - if (resConfig == nullptr) { - return nullptr; - } - resMgr->UpdateResConfig(*resConfig); - - if (!resMgr->AddResource(resourcePath.c_str())) { - ZLOGE("add resource failed, resourcePath is %{public}s", resourcePath.c_str()); - return nullptr; - } - return resMgr; -} - -bool DataShareProfileInfo::GetResFromResMgr(const std::string &resName, ResourceManager &resMgr, - bool isCompressed, std::vector &profileInfos) const -{ - if (resName.empty()) { - return false; - } - - size_t pos = resName.rfind(PROFILE_FILE_PREFIX); - if ((pos == std::string::npos) || (pos == resName.length() - PROFILE_PREFIX_LEN)) { - ZLOGE("res name invalid, resName is %{public}s", resName.c_str()); - return false; - } - std::string profileName = resName.substr(pos + PROFILE_PREFIX_LEN); - // hap is compressed status, get file content. - if (isCompressed) { - ZLOGD("compressed status."); - std::unique_ptr fileContent = nullptr; - size_t len = 0; - RState ret = resMgr.GetProfileDataByName(profileName.c_str(), len, fileContent); - if (ret != SUCCESS || fileContent == nullptr) { - ZLOGE("failed, ret is %{public}d, profileName is %{public}s", - ret, profileName.c_str()); - return false; - } - if (len == 0) { - ZLOGE("fileContent is empty, profileName is %{public}s", profileName.c_str()); - return false; - } - std::string rawData(fileContent.get(), fileContent.get() + len); - if (!Config::IsJson(rawData)) { - ZLOGE("rawData is not json, profileName is %{public}s", profileName.c_str()); - return false; - } - profileInfos.push_back(std::move(rawData)); - return true; - } - // hap is decompressed status, get file path then read file. - std::string resPath; - RState ret = resMgr.GetProfileByName(profileName.c_str(), resPath); - if (ret != SUCCESS) { - ZLOGE("profileName not found, ret is %{public}d, profileName is %{public}s", ret, profileName.c_str()); - return false; - } - std::string profile = ReadProfile(resPath); - if (profile.empty()) { - ZLOGE("Read profile failed, resPath is %{public}s", resPath.c_str()); - return false; - } - profileInfos.push_back(std::move(profile)); - return true; -} - -bool DataShareProfileInfo::IsFileExisted(const std::string &filePath) const -{ - if (filePath.empty()) { - return false; - } - if (access(filePath.c_str(), F_OK) != 0) { - ZLOGE("can not access file, errno is %{public}d, filePath is %{public}s", errno, filePath.c_str()); - return false; - } - return true; -} - -std::string DataShareProfileInfo::ReadProfile(const std::string &resPath) const -{ - if (!IsFileExisted(resPath)) { - return ""; - } - std::fstream in; - in.open(resPath, std::ios_base::in | std::ios_base::binary); - if (!in.is_open()) { - ZLOGE("the file can not open, errno is %{public}d", errno); - return ""; - } - in.seekg(0, std::ios::end); - int64_t size = in.tellg(); - if (size <= 0) { - ZLOGE("the file is empty, resPath is %{public}s", resPath.c_str()); - return ""; - } - in.seekg(0, std::ios::beg); - std::ostringstream tmp; - tmp << in.rdbuf(); - return tmp.str(); -} -} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 63c9fd3ff2c1247aa41dda32c75bba015706f590..833de07f0c05d65f67c74a6c8066a784bf4d7232 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.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 @@ -19,13 +19,21 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" -#include "bundle_constants.h" +#include "bootstrap.h" #include "dataobs_mgr_client.h" +#include "datashare_errno.h" +#include "datashare_template.h" +#include "delete_strategy.h" +#include "directory_manager.h" +#include "get_data_strategy.h" +#include "hap_token_info.h" +#include "insert_strategy.h" #include "ipc_skeleton.h" #include "log_print.h" -#include "rdb_adaptor.h" -#include "uri.h" -#include "uri_utils.h" +#include "publish_strategy.h" +#include "query_strategy.h" +#include "subscribe_strategy.h" +#include "update_strategy.h" #include "utils/anonymous.h" namespace OHOS::DataShare { @@ -33,53 +41,27 @@ using FeatureSystem = DistributedData::FeatureSystem; __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_; DataShareServiceImpl::Factory::Factory() { - FeatureSystem::GetInstance().RegisterCreator("data_share", - []() { return std::make_shared(); }); + FeatureSystem::GetInstance().RegisterCreator("data_share", []() { + return std::make_shared(); + }); } -DataShareServiceImpl::Factory::~Factory() -{ -} +DataShareServiceImpl::Factory::~Factory() {} int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) { ZLOGD("Insert enter."); - UriInfo uriInfo; - if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - ZLOGE("GetInfoFromURI failed!"); - return ERROR; - } - - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - AppExecFwk::BundleInfo bundleInfo; - if (!PermissionProxy::GetBundleInfo(uriInfo.bundleName, tokenId, bundleInfo)) { - ZLOGE("GetBundleInfo failed, BundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return ERROR; + auto context = std::make_shared(uri); + auto ret = InsertStrategy::Execute(context, valuesBucket); + if (ret) { + NotifyChange(uri); + return ret; } - - auto permissionState = VerifyPermission(tokenId, PermissionType::WRITE_PERMISSION, bundleInfo); - if (permissionState == PermissionProxy::PermissionState::DENIED) { - ZLOGE("Verify permission failed, bundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return ERROR; - } - - uriInfo.SetTableName(GetRealityTableName(tokenId, bundleInfo, uriInfo)); - auto userId = GetUserId(tokenId, bundleInfo.singleton); - int32_t ret = RdbAdaptor::Insert(uriInfo, valuesBucket, userId); - if (ret == ERROR) { - ZLOGE("Insert error, uri is %{public}s", DistributedData::Anonymous::Change(uri).c_str()); - return ERROR; - } - NotifyChange(uri); return ret; } bool DataShareServiceImpl::NotifyChange(const std::string &uri) { - ZLOGD("Start"); - ZLOGE("NotifyChange Uri = %{public}s", DistributedData::Anonymous::Change(uri).c_str()); auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance(); if (obsMgrClient == nullptr) { ZLOGE("obsMgrClient is nullptr"); @@ -98,137 +80,203 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred const DataShareValuesBucket &valuesBucket) { ZLOGD("Update enter."); - UriInfo uriInfo; - if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - ZLOGE("GetInfoFromURI failed!"); - return ERROR; - } - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - AppExecFwk::BundleInfo bundleInfo; - if (!PermissionProxy::GetBundleInfo(uriInfo.bundleName, tokenId, bundleInfo)) { - ZLOGE("GetBundleInfo failed, BundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return ERROR; + auto context = std::make_shared(uri); + auto ret = UpdateStrategy::Execute(context, predicate, valuesBucket); + if (ret) { + NotifyChange(uri); + return ret; } - - auto permissionState = VerifyPermission(tokenId, PermissionType::WRITE_PERMISSION, bundleInfo); - if (permissionState == PermissionProxy::PermissionState::DENIED) { - ZLOGE("Verify permission failed, bundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return ERROR; - } - - uriInfo.SetTableName(GetRealityTableName(tokenId, bundleInfo, uriInfo)); - auto userId = GetUserId(tokenId, bundleInfo.singleton); - int32_t ret = RdbAdaptor::Update(uriInfo, predicate, valuesBucket, userId); - if (ret == ERROR) { - ZLOGE("Update error, uri is %{public}s", DistributedData::Anonymous::Change(uri).c_str()); - return ERROR; - } - NotifyChange(uri); return ret; } int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePredicates &predicate) { ZLOGD("Delete enter."); - UriInfo uriInfo; - if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - ZLOGE("GetInfoFromURI failed!"); - return ERROR; + auto context = std::make_shared(uri); + auto ret = DeleteStrategy::Execute(context, predicate); + if (ret) { + NotifyChange(uri); + return ret; } + return ret; +} - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - AppExecFwk::BundleInfo bundleInfo; - if (!PermissionProxy::GetBundleInfo(uriInfo.bundleName, tokenId, bundleInfo)) { - ZLOGE("GetBundleInfo failed, BundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return ERROR; - } +std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) +{ + ZLOGD("Query enter."); + auto context = std::make_shared(uri); + return QueryStrategy::Execute(context, predicates, columns, errCode); +} - auto permissionState = VerifyPermission(tokenId, PermissionType::WRITE_PERMISSION, bundleInfo); - if (permissionState == PermissionProxy::PermissionState::DENIED) { - ZLOGE("Verify permission failed, bundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); +int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) +{ + TemplateId tpltId; + tpltId.subscriberId_ = subscriberId; + if (!GetCallerBundleName(tpltId.bundleName_)) { + ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } + return ERROR; +} - uriInfo.SetTableName(GetRealityTableName(tokenId, bundleInfo, uriInfo)); - auto userId = GetUserId(tokenId, bundleInfo.singleton); - int32_t ret = RdbAdaptor::Delete(uriInfo, predicate, userId); - if (ret == ERROR) { - ZLOGE("Delete error, uri is %{public}s", DistributedData::Anonymous::Change(uri).c_str()); +int32_t DataShareServiceImpl::DelTemplate(const std::string &uri, const int64_t subscriberId) +{ + TemplateId tpltId; + tpltId.subscriberId_ = subscriberId; + if (!GetCallerBundleName(tpltId.bundleName_)) { + ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } - NotifyChange(uri); - return ret; + return ERROR; } -std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, - const DataSharePredicates &predicates, const std::vector &columns, int &errCode) +bool DataShareServiceImpl::GetCallerBundleName(std::string &bundleName) { - ZLOGD("Query enter."); - UriInfo uriInfo; - if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - ZLOGE("GetInfoFromURI failed!"); - return nullptr; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) != Security::AccessToken::TOKEN_HAP) { + return false; } + Security::AccessToken::HapTokenInfo tokenInfo; + auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (result != Security::AccessToken::RET_SUCCESS) { + ZLOGE("token:0x%{public}x, result:%{public}d", tokenId, result); + return false; + } + bundleName = tokenInfo.bundleName; + return true; +} + +std::vector DataShareServiceImpl::Publish(const Data &data, const std::string &bundleNameOfProvider) +{ + return std::vector(); +} - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - AppExecFwk::BundleInfo bundleInfo; - if (!PermissionProxy::GetBundleInfo(uriInfo.bundleName, tokenId, bundleInfo)) { - ZLOGE("GetBundleInfo failed, BundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return nullptr; +Data DataShareServiceImpl::GetData(const std::string &bundleNameOfProvider) +{ + return Data(); +} + +std::vector DataShareServiceImpl::SubscribeRdbData( + const std::vector &uris, const TemplateId &id, const sptr observer) +{ + return std::vector(); +} + +std::vector DataShareServiceImpl::UnsubscribeRdbData( + const std::vector &uris, const TemplateId &id) +{ + std::vector results; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { + return true; + })); } - - auto permissionState = VerifyPermission(tokenId, PermissionType::READ_PERMISSION, bundleInfo); - if (permissionState == PermissionProxy::PermissionState::DENIED) { - ZLOGE("Verify permission failed, bundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return nullptr; + return results; +} + +std::vector DataShareServiceImpl::EnableRdbSubs( + const std::vector &uris, const TemplateId &id) +{ + std::vector results; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { + return true; + })); } - - uriInfo.SetTableName(GetRealityTableName(tokenId, bundleInfo, uriInfo)); - auto userId = GetUserId(tokenId, bundleInfo.singleton); - return RdbAdaptor::Query(uriInfo, predicates, columns, userId, errCode); -} - -std::string DataShareServiceImpl::GetRealityTableName(uint32_t tokenId, const AppExecFwk::BundleInfo &bundleInfo, - const UriInfo &uriInfo) -{ - auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); - bool isSingleApp; - ProfileInfo profileInfo; - if (!dataShareProfileInfo_.GetProfileInfoFromExtension(bundleInfo, profileInfo, isSingleApp)) { - ZLOGE("failed, BundleName is %{public}s, tokenId is %{public}x", - uriInfo.bundleName.c_str(), tokenId); - return uriInfo.tableName; + return results; +} + +std::vector DataShareServiceImpl::DisableRdbSubs( + const std::vector &uris, const TemplateId &id) +{ + std::vector results; + for (const auto &uri : uris) { + auto context = std::make_shared(uri); + results.emplace_back(uri, SubscribeStrategy::Execute(context, [&id, &context]() -> bool { + return true; + })); } - return PermissionProxy::GetTableNameByCrossUserMode(profileInfo, userId, isSingleApp, uriInfo); + return results; } +std::vector DataShareServiceImpl::SubscribePublishedData(const std::vector &uris, + const int64_t subscriberId, const sptr observer) +{ + return std::vector(); +} -PermissionProxy::PermissionState DataShareServiceImpl::VerifyPermission(uint32_t tokenID, - DataShareServiceImpl::PermissionType permissionType, const AppExecFwk::BundleInfo &bundleInfo) +std::vector DataShareServiceImpl::UnsubscribePublishedData(const std::vector &uris, + const int64_t subscriberId) { - std::string permission; - switch (permissionType) { - case PermissionType::READ_PERMISSION: { - return PermissionProxy::QueryReadPermission(tokenID, permission, bundleInfo); - } - case PermissionType::WRITE_PERMISSION: { - return PermissionProxy::QueryWritePermission(tokenID, permission, bundleInfo); - } - } - return PermissionProxy::PermissionState::NOT_FIND; + return std::vector(); } -int32_t DataShareServiceImpl::GetUserId(uint32_t tokenId, bool isSingleApp) +std::vector DataShareServiceImpl::EnablePubSubs(const std::vector &uris, + const int64_t subscriberId) { - if (isSingleApp) { - return 0; - } - return DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + return std::vector(); +} + +std::vector DataShareServiceImpl::DisablePubSubs(const std::vector &uris, + const int64_t subscriberId) +{ + return std::vector(); +} + +enum DataShareKvStoreType : int32_t { + DATA_SHARE_SINGLE_VERSION = 0, + DISTRIBUTED_TYPE_BUTT +}; + +int32_t DataShareServiceImpl::OnInitialize() +{ + auto token = IPCSkeleton::GetCallingTokenID(); + const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); + const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token); + DistributedData::StoreMetaData saveMeta; + saveMeta.appType = "default"; + saveMeta.storeId = "data_share_data_"; + saveMeta.isAutoSync = false; + saveMeta.isBackup = false; + saveMeta.isEncrypt = false; + saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.user = std::to_string(userId); + saveMeta.account = accountId; + saveMeta.tokenId = token; + saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; + saveMeta.area = 1; + saveMeta.uid = IPCSkeleton::GetCallingUid(); + saveMeta.storeType = DATA_SHARE_SINGLE_VERSION; + saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); + KvDBDelegate::GetInstance(false, saveMeta.dataDir); + return EOK; +} + +int32_t DataShareServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) +{ + auto token = IPCSkeleton::GetCallingTokenID(); + const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); + DistributedData::StoreMetaData saveMeta; + saveMeta.appType = "default"; + saveMeta.storeId = "data_share_data_"; + saveMeta.isAutoSync = false; + saveMeta.isBackup = false; + saveMeta.isEncrypt = false; + saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + saveMeta.user = user; + saveMeta.account = account; + saveMeta.tokenId = token; + saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; + saveMeta.area = 1; + saveMeta.uid = IPCSkeleton::GetCallingUid(); + saveMeta.storeType = DATA_SHARE_SINGLE_VERSION; + saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); + KvDBDelegate::GetInstance(true, saveMeta.dataDir); + return EOK; } } // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.h b/services/distributeddataservice/service/data_share/data_share_service_impl.h index 7b9d9d35cc3bd8aa6daec85b8b6ab15ede505db1..6cf140308f8a71f59f64feb9e1a3855bd0b00510 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.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 @@ -18,12 +18,11 @@ #include -#include "bundle_info.h" #include "data_share_service_stub.h" -#include "data_share_profile_info.h" -#include "permission_proxy.h" -#include "visibility.h" +#include "datashare_template.h" +#include "data_proxy_observer.h" #include "uri_utils.h" +#include "visibility.h" namespace OHOS::DataShare { class API_EXPORT DataShareServiceImpl : public DataShareServiceStub { @@ -35,6 +34,29 @@ public: int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) override; std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) override; + int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) override; + int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) override; + std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) override; + Data GetData(const std::string &bundleNameOfProvider) override; + std::vector SubscribeRdbData(const std::vector &uris, + const TemplateId &id, const sptr observer) override; + std::vector UnsubscribeRdbData( + const std::vector &uris, const TemplateId &id) override; + std::vector EnableRdbSubs( + const std::vector &uris, const TemplateId &id) override; + std::vector DisableRdbSubs( + const std::vector &uris, const TemplateId &id) override; + std::vector SubscribePublishedData(const std::vector &uris, + const int64_t subscriberId, const sptr observer) override; + std::vector UnsubscribePublishedData(const std::vector &uris, + const int64_t subscriberId) override; + std::vector EnablePubSubs(const std::vector &uris, + const int64_t subscriberId) override; + std::vector DisablePubSubs(const std::vector &uris, + const int64_t subscriberId) override; + int32_t OnInitialize() override; + int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + private: class Factory { public: @@ -48,14 +70,9 @@ private: }; bool NotifyChange(const std::string &uri); - PermissionProxy::PermissionState VerifyPermission(uint32_t tokenID, PermissionType permissionType, - const AppExecFwk::BundleInfo &bundleInfo); - int32_t GetUserId(uint32_t tokenID, bool isSingleApp); - std::string GetRealityTableName(uint32_t tokenId, const AppExecFwk::BundleInfo &bundleInfo, - const UriInfo &uriInfo); + bool GetCallerBundleName(std::string &bundleName); static Factory factory_; static constexpr int32_t ERROR = -1; - DataShareProfileInfo dataShareProfileInfo_; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index ba7fe7c77c0d444e21b87f268f06eedd746e9cbf..023f4e757bc56ad598e4cdfdd6b667aef937ec8f 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.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 @@ -17,10 +17,12 @@ #include "data_share_service_stub.h" -#include +#include "data_share_obs_proxy.h" +#include "ipc_skeleton.h" #include "ishared_result_set.h" #include "itypes_util.h" #include "log_print.h" +#include "utils/anonymous.h" namespace OHOS { namespace DataShare { @@ -40,13 +42,14 @@ int32_t DataShareServiceStub::OnRemoteInsert(MessageParcel &data, MessageParcel std::string uri; DataShareValuesBucket bucket; if (!ITypesUtil::Unmarshal(data, uri, bucket.valuesMap)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), + bucket.valuesMap.size()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = Insert(uri, bucket); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("OnRemoteInsert fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -57,13 +60,14 @@ int32_t DataShareServiceStub::OnRemoteUpdate(MessageParcel &data, MessageParcel DataSharePredicates predicate; DataShareValuesBucket bucket; if (!ITypesUtil::Unmarshal(data, uri, predicate, bucket.valuesMap)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), + bucket.valuesMap.size()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = Update(uri, predicate, bucket); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("OnRemoteUpdate fail %d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -73,13 +77,13 @@ int32_t DataShareServiceStub::OnRemoteDelete(MessageParcel &data, MessageParcel std::string uri; DataSharePredicates predicate; if (!ITypesUtil::Unmarshal(data, uri, predicate)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal uri:%{public}s", DistributedData::Anonymous::Change(uri).c_str()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = Delete(uri, predicate); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("OnRemoteDelete fail %d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -90,14 +94,218 @@ int32_t DataShareServiceStub::OnRemoteQuery(MessageParcel &data, MessageParcel & DataSharePredicates predicate; std::vector columns; if (!ITypesUtil::Unmarshal(data, uri, predicate, columns)) { + ZLOGE("Unmarshal uri:%{public}s columns size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), + columns.size()); + return IPC_STUB_INVALID_DATA_ERR; + } + int status = 0; + auto result = ISharedResultSet::WriteToParcel(Query(uri, predicate, columns, status), reply); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteAddTemplate(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + int64_t subscriberId; + Template tpl; + if (!ITypesUtil::Unmarshal(data, uri, subscriberId, tpl.predicates_, tpl.scheduler_)) { + ZLOGW("read device list failed."); + return -1; + } + int32_t status = AddTemplate(uri, subscriberId, tpl); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteDelTemplate(MessageParcel &data, MessageParcel &reply) +{ + std::string uri; + int64_t subscriberId; + if (!ITypesUtil::Unmarshal(data, uri, subscriberId)) { ZLOGW("read device list failed."); return -1; } - int errCode = 0; - auto result = ISharedResultSet::WriteToParcel(Query(uri, predicate, columns, errCode), reply); - reply.WriteInt32(errCode); - if (result == nullptr) { - ZLOGW("!resultSet->Marshalling(reply)"); + int32_t status = DelTemplate(uri, subscriberId); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemotePublish(MessageParcel &data, MessageParcel &reply) +{ + Data publishData; + std::string bundleName; + if (!ITypesUtil::Unmarshal(data, publishData.datas_, publishData.version_, bundleName)) { + ZLOGW("read device list failed."); + return -1; + } + std::vector results = Publish(publishData, bundleName); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteGetData(MessageParcel &data, MessageParcel &reply) +{ + std::string bundleName; + if (!ITypesUtil::Unmarshal(data, bundleName)) { + ZLOGW("read device list failed."); + return -1; + } + ZLOGE("hanlu bundleName %{public}s", bundleName.c_str()); + auto results = GetData(bundleName); + if (!ITypesUtil::Marshal(reply, results.datas_)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteSubscribeRdbData(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + TemplateId templateId; + if (!ITypesUtil::Unmarshal(data, uris, templateId)) { + ZLOGE("read device list failed."); + return -1; + } + auto remoteObj = data.ReadRemoteObject(); + sptr observer = new (std::nothrow)RdbObserverProxy(remoteObj); + if (observer == nullptr) { + ZLOGE("obServer is nullptr"); + return -1; + } + std::vector results = SubscribeRdbData(uris, templateId, observer); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteUnsubscribeRdbData(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + TemplateId templateId; + if (!ITypesUtil::Unmarshal(data, uris, templateId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = UnsubscribeRdbData(uris, templateId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteEnableRdbSubs(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + TemplateId templateId; + if (!ITypesUtil::Unmarshal(data, uris, templateId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = EnableRdbSubs(uris, templateId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteDisableRdbSubs(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + TemplateId templateId; + if (!ITypesUtil::Unmarshal(data, uris, templateId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = DisableRdbSubs(uris, templateId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteSubscribePublishedData(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + int64_t subscriberId; + if (!ITypesUtil::Unmarshal(data, uris, subscriberId)) { + ZLOGE("read device list failed."); + return -1; + } + sptr observer = new (std::nothrow)PublishedDataObserverProxy(data.ReadRemoteObject()); + if (observer == nullptr) { + ZLOGE("obServer is nullptr"); + return -1; + } + std::vector results = SubscribePublishedData(uris, subscriberId, observer); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteUnsubscribePublishedData(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + int64_t subscriberId; + if (!ITypesUtil::Unmarshal(data, uris, subscriberId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = UnsubscribePublishedData(uris, subscriberId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteEnablePubSubs(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + int64_t subscriberId; + if (!ITypesUtil::Unmarshal(data, uris, subscriberId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = EnablePubSubs(uris, subscriberId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); + return -1; + } + return 0; +} + +int32_t DataShareServiceStub::OnRemoteDisablePubSubs(MessageParcel &data, MessageParcel &reply) +{ + std::vector uris; + int64_t subscriberId; + if (!ITypesUtil::Unmarshal(data, uris, subscriberId)) { + ZLOGE("read device list failed."); + return -1; + } + std::vector results = DisablePubSubs(uris, subscriberId); + if (!ITypesUtil::Marshal(reply, results)) { + ZLOGE("ITypesUtil::Marshal(reply, results) failed"); return -1; } return 0; diff --git a/services/distributeddataservice/service/data_share/data_share_service_stub.h b/services/distributeddataservice/service/data_share/data_share_service_stub.h index 043a6874dc347f18ca386c6bcbd83ee3c0e93406..b786529f4b2d05dd9a204d64e33d0c2abd3c742e 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/services/distributeddataservice/service/data_share/data_share_service_stub.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 @@ -31,14 +31,36 @@ private: int32_t OnRemoteUpdate(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteDelete(MessageParcel& data, MessageParcel& reply); int32_t OnRemoteQuery(MessageParcel& data, MessageParcel& reply); - + int32_t OnRemoteAddTemplate(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteDelTemplate(MessageParcel& data, MessageParcel& reply); + int32_t OnRemotePublish(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteGetData(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteSubscribeRdbData(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteUnsubscribeRdbData(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteEnableRdbSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteDisableRdbSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteSubscribePublishedData(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteUnsubscribePublishedData(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteEnablePubSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteDisablePubSubs(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (DataShareServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[DATA_SHARE_SERVICE_CMD_MAX] = { &DataShareServiceStub::OnRemoteInsert, &DataShareServiceStub::OnRemoteDelete, &DataShareServiceStub::OnRemoteUpdate, &DataShareServiceStub::OnRemoteQuery, - }; + &DataShareServiceStub::OnRemoteAddTemplate, + &DataShareServiceStub::OnRemoteDelTemplate, + &DataShareServiceStub::OnRemotePublish, + &DataShareServiceStub::OnRemoteGetData, + &DataShareServiceStub::OnRemoteSubscribeRdbData, + &DataShareServiceStub::OnRemoteUnsubscribeRdbData, + &DataShareServiceStub::OnRemoteEnableRdbSubs, + &DataShareServiceStub::OnRemoteDisableRdbSubs, + &DataShareServiceStub::OnRemoteSubscribePublishedData, + &DataShareServiceStub::OnRemoteUnsubscribePublishedData, + &DataShareServiceStub::OnRemoteEnablePubSubs, + &DataShareServiceStub::OnRemoteDisablePubSubs }; }; } // namespace DataShare } // namespace OHOS diff --git a/services/distributeddataservice/service/data_share/data_share_types_util.cpp b/services/distributeddataservice/service/data_share/data_share_types_util.cpp index 11d3bd3a0b94501d3a4fa2f1f18e2d6280bf5767..804a6f76dd2797b29efd531352128b806256a99d 100644 --- a/services/distributeddataservice/service/data_share/data_share_types_util.cpp +++ b/services/distributeddataservice/service/data_share/data_share_types_util.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 @@ -45,4 +45,72 @@ bool Unmarshalling(Operation &operation, MessageParcel &parcel) { return ITypesUtil::Unmarshal(parcel, operation.operation, operation.singleParams, operation.multiParams); } + +template<> +bool Unmarshalling(PublishedDataItem &dataItem, MessageParcel &parcel) +{ + return ITypesUtil::Unmarshal(parcel, dataItem.key_, dataItem.subscriberId_, dataItem.value_); +} + +template<> +bool Marshalling(const PublishedDataItem &dataItem, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, dataItem.key_, dataItem.subscriberId_, dataItem.value_); +} + +template<> +bool Unmarshalling(Data &data, MessageParcel &parcel) +{ + return ITypesUtil::Unmarshal(parcel, data.datas_, data.version_); +} + +template<> +bool Unmarshalling(TemplateId &templateId, MessageParcel &parcel) +{ + return ITypesUtil::Unmarshal(parcel, templateId.subscriberId_, templateId.bundleName_); +} + +template<> +bool Marshalling(const TemplateId &templateId, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, templateId.subscriberId_, templateId.bundleName_); +} + +template<> +bool Unmarshalling(PredicateTemplateNode &predicateTemplateNode, MessageParcel &parcel) +{ + return ITypesUtil::Unmarshal(parcel, predicateTemplateNode.key_, predicateTemplateNode.selectSql_); +} + +template<> +bool Marshalling(const RdbChangeNode &changeNode, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_); +} + +template<> +bool Marshalling(const PublishedDataChangeNode &changeNode, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, changeNode.ownerBundleName_, changeNode.datas_); +} + +template<> +bool Marshalling(const OperationResult &operationResult, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, operationResult.key_, operationResult.errCode_); +} + +template<> +bool Unmarshalling(AshmemNode &node, MessageParcel &parcel) +{ + node.isManaged = true; + node.ashmem = parcel.ReadAshmem(); + return true; +} + +template<> +bool Marshalling(const AshmemNode &node, MessageParcel &parcel) +{ + return parcel.WriteAshmem(node.ashmem); +} } \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/data_share_types_util.h b/services/distributeddataservice/service/data_share/data_share_types_util.h index 917c9611121fa83208d7f592e6b254dbe9426bfb..4f4ebf9b597fe64e4319f05a60aab124080e35a3 100644 --- a/services/distributeddataservice/service/data_share/data_share_types_util.h +++ b/services/distributeddataservice/service/data_share/data_share_types_util.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 @@ -15,17 +15,55 @@ #ifndef DATASHARESERVICE_DATA_SHARE_TYPES_UTIL_H #define DATASHARESERVICE_DATA_SHARE_TYPES_UTIL_H + #include "datashare_predicates.h" +#include "datashare_template.h" #include "datashare_values_bucket.h" +#include "data_proxy_observer.h" #include "itypes_util.h" + namespace OHOS::ITypesUtil { using Predicates = DataShare::DataSharePredicates; using Operation = DataShare::OperationItem; +using PublishedDataItem = DataShare::PublishedDataItem; +using Data = DataShare::Data; +using TemplateId = DataShare::TemplateId; +using PredicateTemplateNode = DataShare::PredicateTemplateNode; +using RdbChangeNode = DataShare::RdbChangeNode; +using PublishedDataChangeNode = DataShare::PublishedDataChangeNode; +using OperationResult = DataShare::OperationResult; template<> bool Unmarshalling(Predicates &predicates, MessageParcel &parcel); template<> bool Unmarshalling(Operation &operation, MessageParcel &parcel); + +template<> +bool Unmarshalling(PublishedDataItem &dataItem, MessageParcel &parcel); + +template<> +bool Marshalling(const PublishedDataItem &templateId, MessageParcel &parcel); + +template<> +bool Unmarshalling(Data &data, MessageParcel &parcel); + +template<> +bool Unmarshalling(TemplateId &templateId, MessageParcel &parcel); + +template<> +bool Unmarshalling(PredicateTemplateNode &predicateTemplateNode, MessageParcel &parcel); + +template<> +bool Marshalling(const RdbChangeNode &changeNode, MessageParcel &parcel); + +template<> +bool Marshalling(const PublishedDataChangeNode &changeNode, MessageParcel &parcel); + +template<> +bool Marshalling(const OperationResult &operationResult, MessageParcel &parcel); + +template<> +bool Marshalling(const TemplateId &changeNode, MessageParcel &parcel); }; #endif // DATASHARESERVICE_DATA_SHARE_TYPES_UTIL_H diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..3f44a3739d2354fb04b8ed9150bd0a499a73b6a5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn @@ -0,0 +1,93 @@ +# 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("//build/ohos.gni") + +config("gaussdb_rd_config") { + visibility = [ ":*" ] + include_dirs = [ + "src/common/include", + "src/executor/include", + "src/executor/document", + "src/oh_adapter/include", + "src/oh_adapter/src", + "src/interface/include", + ] + + defines = [ + "SQLITE_ENABLE_SNAPSHOT", + "SQLITE_HAS_CODEC", + "SQLITE_ENABLE_JSON1", + "USING_HILOG_LOGGER", + "USE_SQLITE_SYMBOLS", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", + ] + if (is_debug) { + defines += [ "TRACE_SQLITE_EXECUTE" ] + } +} + +config("gaussdb_rd_public_config") { + visibility = [ "*:*" ] + include_dirs = [ "include" ] +} + +group("build_module") { + deps = [ ":gaussdb_rd" ] +} + +ohos_shared_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/json_common.cpp", + "src/common/src/log_print.cpp", + "src/common/src/os_api.cpp", + "src/executor/base/grd_db_api.cpp", + "src/executor/document/check_common.cpp", + "src/executor/document/grd_document_api.cpp", + "src/executor/document/grd_resultset_api.cpp", + "src/interface/src/collection.cpp", + "src/interface/src/doc_errno.cpp", + "src/interface/src/document_key.cpp", + "src/interface/src/document_store.cpp", + "src/interface/src/document_store_manager.cpp", + "src/interface/src/projection_tree.cpp", + "src/interface/src/result_set.cpp", + "src/interface/src/result_set_common.cpp", + "src/oh_adapter/src/json_object.cpp", + "src/oh_adapter/src/kv_store_manager.cpp", + "src/oh_adapter/src/sqlite_store_executor_impl.cpp", + "src/oh_adapter/src/sqlite_utils.cpp", + ] + + configs = [ ":gaussdb_rd_config" ] + public_configs = [ ":gaussdb_rd_public_config" ] + + deps = [ "//third_party/sqlite:sqlite" ] + + configs += [ "//third_party/cJSON:cJSON_config" ] + ldflags = [ "-Wl,--exclude-libs,ALL" ] + cflags_cc = [ "-fvisibility=hidden" ] + deps += [ "//third_party/cJSON:cjson" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + + subsystem_name = "distributeddatamgr" + part_name = "datamgr_service" +} diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/README.md b/services/distributeddataservice/service/data_share/gaussdb_rd/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c2950de99c22cd251865ca9ab2b502671362864c --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/README.md @@ -0,0 +1 @@ +# Gauss DB RD diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_db_api.h b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h similarity index 77% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_db_api.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h index e607b0f5b1bfda71d69f1a972b168768bba08a2d..cc1da4b99893780debae8e44b0ce03ca6acfcb03 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_db_api.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_db_api.h @@ -16,15 +16,19 @@ #ifndef GRD_DB_API_H #define GRD_DB_API_H +#include + #include "grd_type_export.h" #ifdef __cplusplus extern "C" { #endif // __cplusplus -int GRD_DBOpen(const char *dbPath, const char *configStr, unsigned int flags, GRD_DB **db); +GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db); + +GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags); -int GRD_DBClose(GRD_DB *db, unsigned int flags); +GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags); #ifdef __cplusplus } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_error.h b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_error.h similarity index 100% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_error.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_error.h diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_resultset_api.h b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h similarity index 74% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_resultset_api.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h index 27a64277602d6f60dca5299cd4f19c2fa01c1672..c9365f189c2f21a3f9da8f217db78d44d68d1b2c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_resultset_api.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_resultset_api.h @@ -16,19 +16,23 @@ #ifndef GRD_RESULTSET_API_H #define GRD_RESULTSET_API_H +#include + +#include "grd_base/grd_type_export.h" + #ifdef __cplusplus extern "C" { #endif // __cplusplus typedef struct GRD_ResultSet GRD_ResultSet; -int GRD_Next(GRD_ResultSet *resultSet); +GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet); -int GRD_GetValue(GRD_ResultSet *resultSet, char **value); +GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value); -int GRD_FreeValue(char *value); +GRD_API int32_t GRD_FreeValue(char *value); -int GRD_FreeResultSet(GRD_ResultSet *resultSet); +GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet); #ifdef __cplusplus } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h similarity index 70% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h index ca6163a2ca74a24fe5f6cdb14c5fb8d097cf9a0f..d116ea2263c540ea73c159c185bb57c3c1191dec 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_base/grd_type_export.h @@ -20,21 +20,27 @@ extern "C" { #endif // __cplusplus +#ifndef _WIN32 +#define GRD_API __attribute__((visibility("default"))) +#endif + typedef struct GRD_DB GRD_DB; /** * @brief Open database config */ -#define GRD_DB_OPEN_ONLY 0x00 -#define GRD_DB_OPEN_CREATE 0x01 -#define GRD_DB_OPEN_CHECK_FOR_ABNORMAL 0x02 //check data in database if close abnormally last time, - //if data is corrupted, rebuild the database -#define GRD_DB_OPEN_CHECK 0x04//check data in database when open database, if data is corrupted, rebuild the database. +#define GRD_DB_OPEN_ONLY 0x00 +#define GRD_DB_OPEN_CREATE 0x01 +// check data in database if close abnormally last time, if data is corrupted, rebuild the database +#define GRD_DB_OPEN_CHECK_FOR_ABNORMAL 0x02 +// check data in database when open database, if data is corrupted, rebuild the database. +#define GRD_DB_OPEN_CHECK 0x04 + /** * @brief Close database config */ -#define GRD_DB_CLOSE 0x00 -#define GRD_DB_CLOSE_IGNORE_ERROR 0x01 +#define GRD_DB_CLOSE 0x00 +#define GRD_DB_CLOSE_IGNORE_ERROR 0x01 /** * @brief flush database config @@ -42,7 +48,7 @@ typedef struct GRD_DB GRD_DB; #define GRD_DB_FLUSH_ASYNC 0x00 #define GRD_DB_FLUSH_SYNC 0x01 -#define GRD_DOC_ID_DISPLAY 0x01 +#define GRD_DOC_ID_DISPLAY 0x01 typedef struct Query { const char *filter; const char *projection; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_document/grd_document_api.h b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h similarity index 49% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_document/grd_document_api.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h index 96ad01e3b0a7f4bac02fa77e3861bf317d6489eb..bd6e77c2db64e861e84c7d5b771cd2fa9a676398 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_document/grd_document_api.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/include/grd_document/grd_document_api.h @@ -16,28 +16,31 @@ #ifndef GRD_DOCUMENT_API_H #define GRD_DOCUMENT_API_H -#include "grd_base/grd_type_export.h" +#include + #include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" #ifdef __cplusplus extern "C" { #endif -int GRD_CreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, unsigned int flags); - -int GRD_DropCollection(GRD_DB *db, const char *collectionName, unsigned int flags); +GRD_API int32_t GRD_CreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags); -int GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char *document, unsigned int flags); +GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint32_t flags); -int GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, unsigned int flags, GRD_ResultSet **resultSet); +GRD_API int32_t GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char *document, uint32_t flags); -int GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *update, unsigned int flags); +GRD_API int32_t GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, uint32_t flags, + GRD_ResultSet **resultSet); -int GRD_UpSertDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *document, unsigned int flags); +GRD_API int32_t GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *update, + uint32_t flags); -int GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, unsigned int flags); +GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *document, + uint32_t flags); -int GRD_Flush(GRD_DB *db, unsigned int flags); +GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, uint32_t flags); #ifdef __cplusplus } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/collection_option.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h similarity index 92% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/collection_option.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h index 727592400325ca7e56f8980a1befde71dbad0b04..6062f9fec76d23cb0179f39dfc5eda368e381599 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/collection_option.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h @@ -16,7 +16,6 @@ #ifndef COLLECTION_OPTION_H #define COLLECTION_OPTION_H -#include #include namespace DocumentDB { @@ -24,11 +23,9 @@ class CollectionOption final { public: static CollectionOption ReadOption(const std::string &optStr, int &errCode); - uint32_t GetMaxDoc() const; - std::string ToString() const; - bool operator==(const CollectionOption &targetOption) const; bool operator!=(const CollectionOption &targetOption) const; + private: std::string option_ = "{}"; uint32_t maxDoc_ = UINT32_MAX; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/db_config.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h similarity index 82% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/db_config.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h index c04116f2a8931a7b6ee4aa2722d5c042f500503d..faa1cca2e7d8a67d9591d65dae6c4bc5fbd2c636 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/db_config.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_config.h @@ -23,7 +23,9 @@ class DBConfig final { public: static DBConfig ReadConfig(const std::string &confStr, int &errCode); + DBConfig() = default; ~DBConfig() = default; + std::string ToString() const; int32_t GetPageSize() const; @@ -31,14 +33,16 @@ public: bool operator==(const DBConfig &targetConfig) const; bool operator!=(const DBConfig &targetConfig) const; + bool CheckPersistenceEqual(const DBConfig &targetConfig) const; + private: - DBConfig() = default; + static DBConfig GetDBConfigFromJsonStr(const std::string &confStr, int &errCode); std::string configStr_ = {}; - int32_t pageSize_ = 4; // 4: default page size k + int32_t pageSize_ = 4; // 4: default page size k uint32_t redoFlushByTrx_ = 0; uint32_t redoPubBufSize_ = 1024; // 1024: default 1024k buff size - int32_t maxConnNum_ = 100; // 100: default max conn + int32_t maxConnNum_ = 100; // 100: default max conn uint32_t bufferPoolSize_ = 1024; // 100: default 1024k pool size uint32_t crcCheckEnable_ = 1; }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h similarity index 71% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/BUILD.gn rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h index bf1a5b8fc72d85936a2f667b614f582a6b071e55..7bafc8020912d9686a4c2108c41b481bc9f1623d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/BUILD.gn +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/db_constant.h @@ -11,4 +11,17 @@ * 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. -*/ \ No newline at end of file +*/ + +#ifndef DB_CONSTANT_H +#define DB_CONSTANT_H + +#include + +namespace DocumentDB { +class DBConstant final { +public: + static const std::string COLL_PREFIX; // = "GRD_COLL_"; +}; +} // namespace DocumentDB +#endif // DB_CONSTANT_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_limit.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h similarity index 89% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_limit.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h index 38ceb943f64f845d8f87a30950712a586895d4b1..fc2515f323e0e25c6af78f73b3e57930d62b60db 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_limit.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h @@ -17,6 +17,6 @@ #define DOC_LIMIT_H namespace DocumentDB { -constexpr const int MAX_DB_CONFIG_LEN = 512 * 1024; // 512 * 1024: 512k length +constexpr int MAX_DB_CONFIG_LEN = 1024 * 1024; // 1024 * 1024: 1024k length } // namespace DocumentDB #endif // DOC_LIMIT_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h new file mode 100644 index 0000000000000000000000000000000000000000..0c767b9aed79fd14136cfdbea0e9c33f38e475c3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h @@ -0,0 +1,34 @@ +/* +* 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 DOCUMENT_TYPE_H +#define DOCUMENT_TYPE_H + +#include + +#include "projection_tree.h" + +namespace DocumentDB { +struct QueryContext { + std::string collectionName; + std::string filter; + std::vector> projectionPath; + ProjectionTree projectionTree; + bool ifShowId = false; + bool viewType = false; + bool isIdExist = false; +}; +} // namespace DocumentDB +#endif // DOCUMENT_TYPE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/json_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/json_common.h new file mode 100644 index 0000000000000000000000000000000000000000..a3a2b61d889f66a939804d262e82ccae25b2395a --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/json_common.h @@ -0,0 +1,52 @@ +/* +* 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 JSON_COMMON_H +#define JSON_COMMON_H + +#include +#include +#include +#include + +#include "json_object.h" + +namespace DocumentDB { +class JsonCommon { +public: + static ValueObject GetValueInSameLevel(JsonObject &node, const std::string &field); + static ValueObject GetValueInSameLevel(JsonObject &node, const std::string &field, bool &isFieldExist); + static bool CheckJsonField(JsonObject &node); + static bool CheckProjectionField(JsonObject &node, int &errCode); + static int ParseNode(JsonObject &Node, std::vector singlePath, + std::vector> &resultPath, bool isFirstLevel); + static std::vector> ParsePath(const JsonObject &node, int &errCode); + static std::vector GetLeafValue(const JsonObject &node); + static bool isValueEqual(const ValueObject &srcValue, const ValueObject &targetValue); + static int Append(const JsonObject &src, const JsonObject &add, bool isReplace); + static bool IsJsonNodeMatch(const JsonObject &src, const JsonObject &target, int &errCode); + +private: + static bool JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, + bool &isCollapse, int &isMatchFlag); + static bool CheckNode(JsonObject &Node); + static bool CheckProjectionNode(JsonObject &Node, bool isFirstLevel, int &errCode); + static void CheckLeafNode(const JsonObject &Node, std::vector &leafValue); + static bool IsArrayMatch(const JsonObject &src, const JsonObject &target, int &isAlreadyMatched); + static bool IsObjectItemMatch(const JsonObject &srcItem, const JsonObject &item, int &isAlreadyMatched, + bool &isCollapse, int &isMatchFlag); +}; +} // namespace DocumentDB +#endif // JSON_COMMON_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/log_print.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h similarity index 57% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/log_print.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h index 55c800a94be0def392e1400e14cf3bba6750c365..2b6774da15e9853b77b9d396bc252cddb16567eb 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/log_print.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/log_print.h @@ -19,9 +19,9 @@ #include namespace DocumentDB { -constexpr const char *LOG_TAG_DOC = "DocumentDB"; +constexpr const char *LOG_TAG_DOC = "GAUSSDB_RD"; -class Logger { +class LogPrint { public: enum class Level { LEVEL_DEBUG, @@ -31,14 +31,14 @@ public: LEVEL_FATAL }; - static void Log(Level level, const std::string &tag, const char *func, int line, const char *format, ...); + static void Log(Level level, const char *tag, const char *format, ...); }; } // namespace DocumentDB #define NO_LOG(...) // No log in normal and release. Used for convenience when deep debugging -#define GLOGD(...) Logger::Log(Logger::Level::LEVEL_DEBUG, LOG_TAG_DOC, __FUNCTION__, __LINE__, __VA_ARGS__) -#define GLOGI(...) Logger::Log(Logger::Level::LEVEL_INFO, LOG_TAG_DOC, __FUNCTION__, __LINE__, __VA_ARGS__) -#define GLOGW(...) Logger::Log(Logger::Level::LEVEL_WARN, LOG_TAG_DOC, __FUNCTION__, __LINE__, __VA_ARGS__) -#define GLOGE(...) Logger::Log(Logger::Level::LEVEL_ERROR, LOG_TAG_DOC, __FUNCTION__, __LINE__, __VA_ARGS__) -#define GLOGF(...) Logger::Log(Logger::Level::LEVEL_FATAL, LOG_TAG_DOC, __FUNCTION__, __LINE__, __VA_ARGS__) +#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__) +#define GLOGE(...) LogPrint::Log(LogPrint::Level::LEVEL_ERROR, LOG_TAG_DOC, __VA_ARGS__) +#define GLOGF(...) LogPrint::Log(LogPrint::Level::LEVEL_FATAL, LOG_TAG_DOC, __VA_ARGS__) #endif // LOG_PRINT_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/os_api.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h similarity index 90% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/os_api.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h index 6bfbf3bb5742f41f9652fde989bbc63955a948b1..e735edb95213855826e6e14d3231a322118a26c0 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/os_api.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/os_api.h @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - #ifndef OS_API_H #define OS_API_H + +#include + namespace DocumentDB { namespace OSAPI { bool CheckPermission(const std::string &filePath); @@ -24,7 +25,7 @@ bool CheckPathExistence(const std::string &filePath); int GetRealPath(const std::string &inOriPath, std::string &outRealPath); -void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName); +void SplitFilePath(const std::string &filePath, std::string &fieldir, std::string &fileName); } // namespace OSAPI } // namespace DocumentDB #endif // OS_API_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp similarity index 72% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp index fcb3da1e104a498199062579447580dea2c2ae56..d5310f73f78a580ed675f06c27ab48b302c5ac9b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp @@ -15,8 +15,8 @@ #include "collection_option.h" -#include #include +#include #include "doc_errno.h" #include "json_object.h" @@ -24,27 +24,23 @@ namespace DocumentDB { namespace { -const std::string OPT_MAX_DOC = "maxdoc"; -const std::vector DB_CONFIG = { - OPT_MAX_DOC, -}; +constexpr const char *OPT_MAX_DOC = "maxdoc"; -bool CheckConfigSupport(const JsonObject &config, int &errCode) +int CheckConfigValid(const JsonObject &config) { - JsonObject child = config.GetChild(); while (!child.IsNull()) { - std::string fieldName = child.GetItemFiled(); - if (std::find(DB_CONFIG.begin(), DB_CONFIG.end(), fieldName) == DB_CONFIG.end()) { + std::string fieldName = child.GetItemField(); + if (strcmp(OPT_MAX_DOC, fieldName.c_str()) != 0) { GLOGE("Invalid collection config."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; + return -E_INVALID_CONFIG_VALUE; } child = child.GetNext(); } - return true; -} + return E_OK; } +} // namespace + CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &errCode) { if (optStr.empty()) { @@ -62,12 +58,13 @@ CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &er return {}; } - if (!CheckConfigSupport(collOpt, errCode)) { + errCode = CheckConfigValid(collOpt); + if (errCode != E_OK) { GLOGE("Check collection option, not support config item. %d", errCode); return {}; } - static const JsonFieldPath maxDocField = {OPT_MAX_DOC}; + static const JsonFieldPath maxDocField = { OPT_MAX_DOC }; if (!collOpt.IsFieldExists(maxDocField)) { return {}; } @@ -95,24 +92,4 @@ CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &er option.option_ = optStr; return option; } - -uint32_t CollectionOption::GetMaxDoc() const -{ - return maxDoc_; -} - -std::string CollectionOption::ToString() const -{ - return option_; -} - -bool CollectionOption::operator==(const CollectionOption &targetOption) const -{ - return maxDoc_ == targetOption.maxDoc_; -} - -bool CollectionOption::operator!=(const CollectionOption &targetOption) const -{ - return !(*this == targetOption); -} -} \ No newline at end of file +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/db_config.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp similarity index 30% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/db_config.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp index b60de5b19c912b46c8e0e1c58ef4737f8345cb8a..5061139eebd491f7adf5a1483d32523328320f42 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/db_config.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp @@ -16,257 +16,187 @@ #include "db_config.h" #include +#include +#include #include #include "doc_errno.h" #include "doc_limit.h" -#include "log_print.h" #include "json_object.h" +#include "log_print.h" namespace DocumentDB { namespace { -const int MIN_REDO_BUFFER_SIZE = 256; -const int MAX_REDO_BUFFER_SIZE = 16384; -const int MIN_CONNECTION_NUM = 16; -const int MAX_CONNECTION_NUM = 1024; -const int MIN_BUFFER_POOL_SIZE = 1024; -const int MAX_BUFFER_POOL_SIZE = 4 * 1024 * 1024; - -const std::string DB_CONFIG_PAGESIZE = "pagesize"; -const std::string DB_CONFIG_REDO_FLUSH_BY_TRX = "redoflushbytrx"; -const std::string DB_CONFIG_REDO_PUB_BUFF_SIZE = "redopubbufsize"; -const std::string DB_CONFIG_MAX_CONN_NUM = "maxconnnum"; -const std::string DB_CONFIG_BUFFER_POOL_SIZE = "bufferpoolsize"; -const std::string DB_CONFIG_CRC_CHECK_ENABLE = "crccheckenable"; - -const std::vector DB_CONFIG = { - DB_CONFIG_PAGESIZE, - DB_CONFIG_REDO_FLUSH_BY_TRX, - DB_CONFIG_REDO_PUB_BUFF_SIZE, - DB_CONFIG_MAX_CONN_NUM, - DB_CONFIG_BUFFER_POOL_SIZE, - DB_CONFIG_CRC_CHECK_ENABLE -}; - -bool CheckPageSizeConfig(const JsonObject &config, int32_t &pageSize, int &errCode) +constexpr int MIN_REDO_BUFFER_SIZE = 256; +constexpr int MAX_REDO_BUFFER_SIZE = 16384; +constexpr int MIN_CONNECTION_NUM = 16; +constexpr int MAX_CONNECTION_NUM = 1024; +constexpr int MIN_BUFFER_POOL_SIZE = 1024; +constexpr int MAX_BUFFER_POOL_SIZE = 4 * 1024 * 1024; + +constexpr const char *DB_CONFIG_PAGESIZE = "pagesize"; +constexpr const char *DB_CONFIG_REDO_FLUSH_BY_TRX = "redoflushbytrx"; +constexpr const char *DB_CONFIG_REDO_PUB_BUFF_SIZE = "redopubbufsize"; +constexpr const char *DB_CONFIG_MAX_CONN_NUM = "maxconnnum"; +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, + DB_CONFIG_REDO_PUB_BUFF_SIZE, DB_CONFIG_MAX_CONN_NUM, DB_CONFIG_BUFFER_POOL_SIZE, DB_CONFIG_CRC_CHECK_ENABLE }; + +template +bool CheckAndGetDBConfig(const JsonObject &config, const std::string &name, const std::function &checkValid, + T &val) { - static const JsonFieldPath pageSizeField = {DB_CONFIG_PAGESIZE}; - if (!config.IsFieldExists(pageSizeField)) { + const JsonFieldPath configField = { name }; + if (!config.IsFieldExists(configField)) { return true; } - ValueObject configValue = config.GetObjectByPath(pageSizeField, errCode); + int errCode = E_OK; + ValueObject configValue = config.GetObjectByPath(configField, errCode); + if (errCode != E_OK) { + GLOGE("Can not find config Value"); + return errCode; + } if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of pageSize is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; + GLOGE("Check DB config failed, not found or type of %s is not NUMBER.", name.c_str()); return false; } - static const std::vector pageSizeValid = {4, 8, 16, 32, 64}; - if (std::find(pageSizeValid.begin(), pageSizeValid.end(), configValue.GetIntValue()) == pageSizeValid.end()) { - GLOGE("Check DB config failed, invalid pageSize value."); - errCode = -E_INVALID_CONFIG_VALUE; + if (checkValid && !checkValid(static_cast(configValue.GetIntValue()))) { + GLOGE("Check DB config failed, invalid %s value.", name.c_str()); return false; } - pageSize = static_cast(configValue.GetIntValue()); + val = static_cast(configValue.GetIntValue()); return true; } -bool CheckRedoFlushConfig(const JsonObject &config, uint32_t &redoFlush, int &errCode) +bool CheckPageSizeConfig(const JsonObject &config, int32_t &pageSize) { - static const JsonFieldPath redoFlushField = {DB_CONFIG_REDO_FLUSH_BY_TRX}; - if (!config.IsFieldExists(redoFlushField)) { - return true; - } - - ValueObject configValue = config.GetObjectByPath(redoFlushField, errCode); - if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of redoFlushByTrx is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - if (configValue.GetIntValue() != 0 && configValue.GetIntValue() != 1) { - GLOGE("Check DB config failed, invalid redoFlushByTrx value."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - redoFlush = static_cast(configValue.GetIntValue()); - return true; + std::function checkFunction = [](int32_t val) { + static const std::vector pageSizeValid = { 4, 8, 16, 32, 64 }; + return std::find(pageSizeValid.begin(), pageSizeValid.end(), val) != pageSizeValid.end(); + }; + return CheckAndGetDBConfig(config, DB_CONFIG_PAGESIZE, checkFunction, pageSize); } -bool CheckRedoBufSizeConfig(const JsonObject &config, uint32_t &redoBufSize, int &errCode) +bool CheckRedoFlushConfig(const JsonObject &config, uint32_t &redoFlush) { - static const JsonFieldPath redoBufSizeField = {DB_CONFIG_REDO_PUB_BUFF_SIZE}; - if (!config.IsFieldExists(redoBufSizeField)) { - return true; - } - - ValueObject configValue = config.GetObjectByPath(redoBufSizeField, errCode); - if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of redoPubBufSize is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - if (configValue.GetIntValue() < MIN_REDO_BUFFER_SIZE || configValue.GetIntValue() > MAX_REDO_BUFFER_SIZE) { - GLOGE("Check DB config failed, invalid redoPubBufSize value."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - redoBufSize = static_cast(configValue.GetIntValue()); - return true; + std::function checkFunction = [](uint32_t val) { + return val == 0 || val == 1; + }; + return CheckAndGetDBConfig(config, DB_CONFIG_REDO_FLUSH_BY_TRX, checkFunction, redoFlush); } -bool CheckMaxConnNumConfig(const JsonObject &config, int32_t &maxConnNum, int &errCode) +bool CheckRedoBufSizeConfig(const JsonObject &config, int32_t pageSize, uint32_t &redoBufSize) { - static const JsonFieldPath maxConnNumField = {DB_CONFIG_MAX_CONN_NUM}; - if (!config.IsFieldExists(maxConnNumField)) { - return true; - } - - ValueObject configValue = config.GetObjectByPath(maxConnNumField, errCode); - if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of maxConnNum is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - if (configValue.GetIntValue() < MIN_CONNECTION_NUM || configValue.GetIntValue() > MAX_CONNECTION_NUM) { - GLOGE("Check DB config failed, invalid maxConnNum value."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - maxConnNum = static_cast(configValue.GetIntValue()); - return true; + std::function checkFunction = [pageSize](uint32_t val) { + return val >= MIN_REDO_BUFFER_SIZE && val <= MAX_REDO_BUFFER_SIZE && + val > static_cast(pageSize * 63); // 63: pool size should be 63 times larger then pageSize + }; + return CheckAndGetDBConfig(config, DB_CONFIG_REDO_PUB_BUFF_SIZE, checkFunction, redoBufSize); } -bool CheckBufferPoolSizeConfig(const JsonObject &config, int32_t pageSize, uint32_t &redoBufSize, - int &errCode) +bool CheckMaxConnNumConfig(const JsonObject &config, int32_t &maxConnNum) { - static const JsonFieldPath bufferPoolSizeField = {DB_CONFIG_BUFFER_POOL_SIZE}; - if (!config.IsFieldExists(bufferPoolSizeField)) { - return true; - } - - ValueObject configValue = config.GetObjectByPath(bufferPoolSizeField, errCode); - if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of bufferPoolSize is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - if (configValue.GetIntValue() < MIN_BUFFER_POOL_SIZE || configValue.GetIntValue() > MAX_BUFFER_POOL_SIZE || - configValue.GetIntValue() < pageSize * 33) { - GLOGE("Check DB config failed, invalid bufferPoolSize value."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - redoBufSize = static_cast(configValue.GetIntValue()); - return true; + std::function checkFunction = [](int32_t val) { + return val >= MIN_CONNECTION_NUM && val <= MAX_CONNECTION_NUM; + }; + return CheckAndGetDBConfig(config, DB_CONFIG_MAX_CONN_NUM, checkFunction, maxConnNum); } -bool CheckCrcCheckEnableConfig(const JsonObject &config, uint32_t &crcCheckEnable, int &errCode) +bool CheckBufferPoolSizeConfig(const JsonObject &config, int32_t pageSize, uint32_t &redoBufSize) { - static const JsonFieldPath crcCheckEnableField = {DB_CONFIG_CRC_CHECK_ENABLE}; - if (!config.IsFieldExists(crcCheckEnableField)) { - return true; - } - - ValueObject configValue = config.GetObjectByPath(crcCheckEnableField, errCode); - if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { - GLOGE("Check DB config failed, the field type of crcCheckEnable is not NUMBER."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } - - if (configValue.GetIntValue() != 0 && configValue.GetIntValue() != 1) { - GLOGE("Check DB config failed, invalid crcCheckEnable value."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; - } + std::function checkFunction = [pageSize](uint32_t val) { + return val >= MIN_BUFFER_POOL_SIZE && val <= MAX_BUFFER_POOL_SIZE && + val >= static_cast(pageSize * 64); // 64: pool size should be 64 times larger then pageSize + }; + return CheckAndGetDBConfig(config, DB_CONFIG_BUFFER_POOL_SIZE, checkFunction, redoBufSize); +} - crcCheckEnable = static_cast(configValue.GetIntValue()); - return true; +bool CheckCrcCheckEnableConfig(const JsonObject &config, uint32_t &crcCheckEnable) +{ + std::function checkFunction = [](uint32_t val) { + return val == 0 || val == 1; + }; + return CheckAndGetDBConfig(config, DB_CONFIG_CRC_CHECK_ENABLE, checkFunction, crcCheckEnable); } -bool CheckConfigSupport(const JsonObject &config, int &errCode) +int CheckConfigValid(const JsonObject &config) { JsonObject child = config.GetChild(); while (!child.IsNull()) { - std::string fieldName = child.GetItemFiled(); - if (std::find(DB_CONFIG.begin(), DB_CONFIG.end(), fieldName) == DB_CONFIG.end()) { + 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) { + isSupport = true; + break; + } + } + + if (!isSupport) { GLOGE("Invalid db config."); - errCode = -E_INVALID_CONFIG_VALUE; - return false; + return -E_INVALID_CONFIG_VALUE; } + child = child.GetNext(); } - return true; -} + return E_OK; } +} // namespace -DBConfig DBConfig::ReadConfig(const std::string &confStr, int &errCode) +DBConfig DBConfig::GetDBConfigFromJsonStr(const std::string &confStr, int &errCode) { - if (confStr.empty()) { - return {}; - } - - if (confStr.length() + 1 > MAX_DB_CONFIG_LEN) { - GLOGE("Config json string is too long."); - errCode = -E_OVER_LIMIT; - return {}; - } - - std::string lowerCaseConfStr = confStr; - std::transform(lowerCaseConfStr.begin(), lowerCaseConfStr.end(), lowerCaseConfStr.begin(), [](unsigned char c) { - return std::tolower(c); - }); - - JsonObject dbConfig = JsonObject::Parse(lowerCaseConfStr, errCode); + JsonObject dbConfig = JsonObject::Parse(confStr, errCode); if (errCode != E_OK) { GLOGE("Read DB config failed from str. %d", errCode); return {}; } - if (!CheckConfigSupport(dbConfig, errCode)) { + errCode = CheckConfigValid(dbConfig); + if (errCode != E_OK) { GLOGE("Check DB config, not support config item. %d", errCode); return {}; } DBConfig conf; - if (!CheckPageSizeConfig(dbConfig, conf.pageSize_, errCode)) { - GLOGE("Check DB config 'pageSize' failed. %d", errCode); + if (!CheckPageSizeConfig(dbConfig, conf.pageSize_)) { + GLOGE("Check DB config 'pageSize' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } - if (!CheckRedoFlushConfig(dbConfig, conf.redoFlushByTrx_, errCode)) { - GLOGE("Check DB config 'redoFlushByTrx' failed. %d", errCode); + if (!CheckRedoFlushConfig(dbConfig, conf.redoFlushByTrx_)) { + GLOGE("Check DB config 'redoFlushByTrx' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } - if (!CheckRedoBufSizeConfig(dbConfig, conf.redoPubBufSize_, errCode)) { - GLOGE("Check DB config 'redoPubBufSize' failed. %d", errCode); + if (!CheckRedoBufSizeConfig(dbConfig, conf.pageSize_, conf.redoPubBufSize_)) { + GLOGE("Check DB config 'redoPubBufSize' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } - if (!CheckMaxConnNumConfig(dbConfig, conf.maxConnNum_, errCode)) { - GLOGE("Check DB config 'maxConnNum' failed. %d", errCode); + if (!CheckMaxConnNumConfig(dbConfig, conf.maxConnNum_)) { + GLOGE("Check DB config 'maxConnNum' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } - if (!CheckBufferPoolSizeConfig(dbConfig, conf.pageSize_, conf.bufferPoolSize_, errCode)) { - GLOGE("Check DB config 'bufferPoolSize' failed. %d", errCode); + if (!CheckBufferPoolSizeConfig(dbConfig, conf.pageSize_, conf.bufferPoolSize_)) { + GLOGE("Check DB config 'bufferPoolSize' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } - if (!CheckCrcCheckEnableConfig(dbConfig, conf.crcCheckEnable_, errCode)) { - GLOGE("Check DB config 'crcCheckEnable' failed. %d", errCode); + if (!CheckCrcCheckEnableConfig(dbConfig, conf.crcCheckEnable_)) { + GLOGE("Check DB config 'crcCheckEnable' failed."); + errCode = -E_INVALID_CONFIG_VALUE; return {}; } @@ -275,6 +205,26 @@ DBConfig DBConfig::ReadConfig(const std::string &confStr, int &errCode) return conf; } +DBConfig DBConfig::ReadConfig(const std::string &confStr, int &errCode) +{ + if (confStr.empty()) { + return {}; + } + + if (confStr.length() + 1 > MAX_DB_CONFIG_LEN) { + GLOGE("Config json string is too long."); + errCode = -E_OVER_LIMIT; + return {}; + } + + std::string lowerCaseConfStr = confStr; + std::transform(lowerCaseConfStr.begin(), lowerCaseConfStr.end(), lowerCaseConfStr.begin(), [](unsigned char c) { + return std::tolower(c); + }); + + return GetDBConfigFromJsonStr(lowerCaseConfStr, errCode); +} + std::string DBConfig::ToString() const { return configStr_; @@ -287,14 +237,18 @@ int32_t DBConfig::GetPageSize() const bool DBConfig::operator==(const DBConfig &targetConfig) const { - return configStr_ == targetConfig.configStr_ && pageSize_ == targetConfig.pageSize_ && - redoFlushByTrx_ == targetConfig.redoFlushByTrx_ && redoPubBufSize_ == targetConfig.redoPubBufSize_ && - maxConnNum_ == targetConfig.maxConnNum_ && bufferPoolSize_ == targetConfig.bufferPoolSize_ && - crcCheckEnable_ == targetConfig.crcCheckEnable_; + return pageSize_ == targetConfig.pageSize_ && redoFlushByTrx_ == targetConfig.redoFlushByTrx_ && + redoPubBufSize_ == targetConfig.redoPubBufSize_ && maxConnNum_ == targetConfig.maxConnNum_ && + bufferPoolSize_ == targetConfig.bufferPoolSize_ && crcCheckEnable_ == targetConfig.crcCheckEnable_; } bool DBConfig::operator!=(const DBConfig &targetConfig) const { return !(*this == targetConfig); } + +bool DBConfig::CheckPersistenceEqual(const DBConfig &targetConfig) const +{ + return pageSize_ == targetConfig.pageSize_ && crcCheckEnable_ == targetConfig.crcCheckEnable_; +} } // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp similarity index 81% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/BUILD.gn rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp index bf1a5b8fc72d85936a2f667b614f582a6b071e55..cbaef55d2b7989f9c60e77db7c9a534be5848791 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/BUILD.gn +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_constant.cpp @@ -11,4 +11,10 @@ * 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. -*/ \ No newline at end of file +*/ + +#include "db_constant.h" + +namespace DocumentDB { +const std::string DBConstant::COLL_PREFIX = "GRD_COLL_"; +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a967d2e69125bd45aa34a6d47f1abba381eea4e8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp @@ -0,0 +1,723 @@ +/* + * 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 "json_common.h" + +#include + +#include "doc_errno.h" +#include "log_print.h" + +namespace DocumentDB { +ValueObject JsonCommon::GetValueInSameLevel(JsonObject &node, const std::string &field) +{ + while (!node.IsNull()) { + if (node.GetItemField() == field) { + ValueObject itemValue = node.GetItemValue(); + return itemValue; + } + if (node.GetNext().IsNull()) { + return ValueObject(); + } + JsonObject nodeNew = node.GetNext(); + node = nodeNew; + } + return ValueObject(); +} + +ValueObject JsonCommon::GetValueInSameLevel(JsonObject &node, const std::string &field, bool &isFieldExist) +{ + while (!node.IsNull()) { + if (node.GetItemField() == field) { + ValueObject itemValue = node.GetItemValue(); + isFieldExist = true; + return itemValue; + } + if (node.GetNext().IsNull()) { + isFieldExist = false; + return ValueObject(); + } + JsonObject nodeNew = node.GetNext(); + node = nodeNew; + } + isFieldExist = false; + return ValueObject(); +} + +void JsonCommon::CheckLeafNode(const JsonObject &node, std::vector &leafValue) +{ + if (node.GetChild().IsNull()) { + ValueObject itemValue = node.GetItemValue(); + leafValue.emplace_back(itemValue); + } + if (!node.GetChild().IsNull()) { + JsonObject nodeNew = node.GetChild(); + CheckLeafNode(nodeNew, leafValue); + } + if (!node.GetNext().IsNull()) { + JsonObject nodeNew = node.GetNext(); + CheckLeafNode(nodeNew, leafValue); + } +} + +std::vector JsonCommon::GetLeafValue(const JsonObject &node) +{ + std::vector leafValue; + if (node.IsNull()) { + GLOGE("Get leafValue faied, node is empty"); + return leafValue; + } + CheckLeafNode(node, leafValue); + return leafValue; +} + +bool JsonCommon::CheckNode(JsonObject &node) +{ + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { + std::set fieldSet; + bool isFieldNameExist = true; + int ret = E_OK; + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); + if (ret != E_OK) { + isFieldNameExist = false; + } + if (fieldSet.find(fieldName) != fieldSet.end()) { + return false; + } + if (isFieldNameExist) { + fieldSet.insert(fieldName); + if (fieldName.empty()) { + return false; + } + } + for (size_t i = 0; i < fieldName.size(); i++) { + if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || fieldName[i] == '_')) { + return false; + } + if (i == 0 && (isdigit(fieldName[i]))) { + return false; + } + } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); + } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); + } + } + return true; +} + +bool JsonCommon::CheckJsonField(JsonObject &jsonObj) +{ + return CheckNode(jsonObj); +} + +bool JsonCommon::CheckProjectionNode(JsonObject &node, bool isFirstLevel, int &errCode) +{ + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { + int ret = 0; + std::set fieldSet; + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); + if (fieldName.empty()) { + errCode = -E_INVALID_ARGS; + return false; + } + if (fieldSet.find(fieldName) == fieldSet.end() && ret == E_OK) { + fieldSet.insert(fieldName); + } else { + errCode = -E_INVALID_JSON_FORMAT; + return false; + } + for (size_t i = 0; i < fieldName.size(); i++) { + if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || (fieldName[i] == '_') || + (isFirstLevel && fieldName[i] == '.'))) { + errCode = -E_INVALID_ARGS; + return false; + } + if (i == 0 && (isdigit(fieldName[i]))) { + errCode = -E_INVALID_ARGS; + return false; + } + } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); + } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); + } + } + return true; +} + +bool JsonCommon::CheckProjectionField(JsonObject &jsonObj, int &errCode) +{ + bool isFirstLevel = true; + return CheckProjectionNode(jsonObj, isFirstLevel, errCode); +} + +namespace { +int SplitFieldName(const std::string &fieldName, std::vector &allFieldsName, int &insertCount) +{ + std::string tempParseName; + std::string priFieldName = fieldName; + for (size_t j = 0; j < priFieldName.size(); j++) { + if (priFieldName[j] != '.') { + tempParseName += priFieldName[j]; + } + if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { + if ((j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') || + (priFieldName[j] == '.' && j == priFieldName.size() - 1)) { + return -E_INVALID_ARGS; + } + allFieldsName.emplace_back(tempParseName); + insertCount++; + tempParseName.clear(); + } + } + return E_OK; +} +} // namespace + +int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, + std::vector> &resultPath, bool isFirstLevel) +{ + while (!node.IsNull()) { + int insertCount = 0; + if (isFirstLevel) { + std::vector allFieldsName; + int errCode = SplitFieldName(node.GetItemField(), allFieldsName, insertCount); + if (errCode != E_OK) { + return errCode; + } + singlePath.insert(singlePath.end(), allFieldsName.begin(), allFieldsName.end()); + } else { + std::vector allFieldsName; + allFieldsName.emplace_back(node.GetItemField()); + insertCount++; + singlePath.insert(singlePath.end(), allFieldsName.begin(), allFieldsName.end()); + } + if (!node.GetChild().IsNull() && node.GetChild().GetItemField() != "") { + JsonObject nodeNew = node.GetChild(); + int ret = ParseNode(nodeNew, singlePath, resultPath, false); + if (ret != E_OK) { + return ret; + } + } else { + resultPath.emplace_back(singlePath); + } + for (int i = 0; i < insertCount; i++) { + singlePath.pop_back(); + } + node = node.GetNext(); + } + return E_OK; +} + +std::vector> JsonCommon::ParsePath(const JsonObject &root, int &errCode) +{ + std::vector> resultPath; + JsonObject projectionJson = root.GetChild(); + std::vector singlePath; + errCode = ParseNode(projectionJson, singlePath, resultPath, true); + return resultPath; +} + +namespace { +JsonFieldPath SplitePath(const JsonFieldPath &path, bool &isCollapse) +{ + if (path.size() > 1 || path.empty()) { // only first level has collapse field + return path; + } + JsonFieldPath splitPath; + const std::string &str = path[0]; + size_t start = 0; + size_t end = 0; + while ((end = str.find('.', start)) != std::string::npos) { + splitPath.push_back(str.substr(start, end - start)); + start = end + 1; + } + if (start < str.length()) { + splitPath.push_back(str.substr(start)); + } + isCollapse = (splitPath.size() > 1); + return splitPath; +} + +JsonFieldPath ExpendPathForField(const JsonFieldPath &path, bool &isCollapse) +{ + JsonFieldPath splitPath; + const std::string &str = path.back(); + size_t start = 0; + size_t end = 0; + while ((end = str.find('.', start)) != std::string::npos) { + splitPath.push_back(str.substr(start, end - start)); + start = end + 1; + } + if (start < str.length()) { + splitPath.push_back(str.substr(start)); + } + isCollapse = (splitPath.size() > 1); + for (size_t i = 1; i < path.size(); i++) { + splitPath.emplace_back(path[i]); + } + return splitPath; +} + +void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, + std::function AppendFoo) +{ + JsonObject child = obj.GetChild(); + while (!child.IsNull()) { + JsonFieldPath childPath = path; + childPath.push_back(child.GetItemField()); + if (AppendFoo != nullptr && AppendFoo(childPath, obj, child)) { + JsonObjectIterator(child, childPath, AppendFoo); + } + child = child.GetNext(); + } +} + +void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, + 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); + } + child = child.GetNext(); + } +} + +bool IsNumber(const std::string &str) +{ + return std::all_of(str.begin(), str.end(), [](char c) { + return std::isdigit(c); + }); +} + +bool AddSpliteHitField(const JsonObject &src, const JsonObject &item, JsonFieldPath &hitPath, + JsonFieldPath &abandonPath, int &externErrCode) +{ + if (hitPath.empty()) { + return true; + } + + int errCode = E_OK; + JsonFieldPath preHitPath = hitPath; + preHitPath.pop_back(); + JsonObject preHitItem = src.FindItem(preHitPath, errCode); + // if FindItem errCode is not E_OK, GetObjectItem errCode should be E_NOT_FOUND + JsonObject hitItem = preHitItem.GetObjectItem(hitPath.back(), errCode); + if (errCode == -E_NOT_FOUND) { + return true; + } + + if (!abandonPath.empty()) { + abandonPath.pop_back(); + } + + if (hitItem.IsNull()) { + return true; + } + + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { + if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { + GLOGE("Add collapse item to object failed, path not exist."); + externErrCode = -E_DATA_CONFLICT; + return false; + } + if (IsNumber(abandonPath[i])) { + externErrCode = -E_DATA_CONFLICT; + return false; + } + errCode = (i == 0) ? hitItem.AddItemToObject(abandonPath[i], item) : hitItem.AddItemToObject(abandonPath[i]); + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + } + return false; +} + +bool AddSpliteField(const JsonObject &src, const JsonObject &item, const JsonFieldPath &itemPath, int &externErrCode) +{ + int errCode = E_OK; + JsonFieldPath abandonPath; + JsonFieldPath hitPath = itemPath; + while (!hitPath.empty()) { + abandonPath.emplace_back(hitPath.back()); + JsonObject srcFatherItem = src.FindItem(hitPath, errCode); + if (errCode == E_OK) { + break; + } + if (!srcFatherItem.IsNull()) { + break; + } + hitPath.pop_back(); + } + + if (!AddSpliteHitField(src, item, hitPath, abandonPath, externErrCode)) { + return false; + } + + JsonObject hitItem = src.FindItem(hitPath, errCode); + if (errCode != E_OK) { + return false; + } + JsonFieldPath newHitPath; + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { + if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { + GLOGE("Add collapse item to object failed, path not exist."); + externErrCode = -E_DATA_CONFLICT; + return false; + } + if (IsNumber(abandonPath[i])) { + externErrCode = -E_DATA_CONFLICT; + return false; + } + errCode = (i == 0 ? hitItem.AddItemToObject(abandonPath[i], item) : hitItem.AddItemToObject(abandonPath[i])); + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + newHitPath.emplace_back(abandonPath[i]); + hitItem = hitItem.FindItem(newHitPath, errCode); + if (errCode != E_OK) { + return false; + } + newHitPath.pop_back(); + } + return false; +} + +bool JsonValueReplace(const JsonObject &src, const JsonFieldPath &fatherPath, const JsonObject &father, + const JsonObject &item, int &externErrCode) +{ + int errCode = E_OK; + JsonFieldPath granPaPath = fatherPath; + if (!granPaPath.empty()) { + granPaPath.pop_back(); + JsonObject fatherItem = src.FindItem(granPaPath, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + fatherItem.ReplaceItemInObject(item.GetItemField().c_str(), item, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + } else { + JsonObject fatherItem = src.FindItem(fatherPath, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + if (father.GetChild().IsNull()) { + externErrCode = -E_NO_DATA; + GLOGE("Replace falied, no data match"); + return false; + } + if (!item.GetItemField(errCode).empty()) { + fatherItem.ReplaceItemInObject(item.GetItemField().c_str(), item, errCode); + if (errCode != E_OK) { + return false; + } + } + } + return true; +} + +bool JsonNodeReplace(const JsonObject &src, const JsonFieldPath &itemPath, const JsonObject &father, + const JsonObject &item, int &externErrCode) +{ + int errCode = E_OK; + JsonFieldPath fatherPath = itemPath; + fatherPath.pop_back(); + if (!fatherPath.empty()) { + JsonObject fatherItem = src.FindItem(fatherPath, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + if (fatherItem.GetType() == JsonObject::Type::JSON_ARRAY && IsNumber(itemPath.back())) { + fatherItem.ReplaceItemInArray(std::stoi(itemPath.back()), item, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + } + return false; + } + fatherItem.ReplaceItemInObject(itemPath.back().c_str(), item, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + } else { + JsonObject fatherItem = src.FindItem(fatherPath, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + if (father.GetChild().IsNull()) { + externErrCode = -E_NO_DATA; + GLOGE("Replace falied, no data match"); + return false; + } + fatherItem.ReplaceItemInObject(itemPath.back().c_str(), item, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find father item in source json object failed. %d", errCode); + return false; + } + } + return true; +} + +bool JsonNodeAppend(const JsonObject &src, const JsonFieldPath &path, const JsonObject &father, const JsonObject &item, + int &externErrCode) +{ + bool isCollapse = false; + JsonFieldPath itemPath = ExpendPathForField(path, isCollapse); + JsonFieldPath fatherPath = itemPath; + fatherPath.pop_back(); + + int errCode = E_OK; + JsonObject srcFatherItem = src.FindItem(fatherPath, errCode); + std::string lastFieldName = itemPath.back(); + if (errCode != E_OK) { + AddSpliteField(src, item, itemPath, externErrCode); + return false; + } + // This condition is to determine that the path has a point operator, + // and the name of the last path cannot be a number or the srcItem to be added is an array, otherwise. + // adding a node with the number fieldName does not legal. + if (isCollapse && (!IsNumber(lastFieldName) || srcFatherItem.GetType() == JsonObject::Type::JSON_ARRAY)) { + errCode = srcFatherItem.AddItemToObject(lastFieldName, item); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Add item to object failed. %d", errCode); + return false; + } + return false; + } + if (!isCollapse) { + bool ret = JsonValueReplace(src, fatherPath, father, item, externErrCode); + if (!ret) { + return false; // replace failed + } + return false; // Different node types, overwrite directly, skip child node + } + GLOGE("Add nothing because data conflict"); + externErrCode = -E_DATA_CONFLICT; + return false; // Source path not exist, overwrite directly, skip child node +} +} // namespace + +int JsonCommon::Append(const JsonObject &src, const JsonObject &add, bool isReplace) +{ + int externErrCode = E_OK; + JsonObjectIterator(add, {}, + [&src, &externErrCode, &isReplace](const JsonFieldPath &path, + const JsonObject &father, const JsonObject &item) { + bool isCollapse = false; // Whether there is a path generated by the dot operator, such as t1.t2.t3 + JsonFieldPath itemPath = ExpendPathForField(path, isCollapse); + if (src.IsFieldExists(itemPath)) { + int errCode = E_OK; + JsonObject srcItem = src.FindItem(itemPath, errCode); + if (errCode != E_OK) { + externErrCode = (externErrCode == E_OK ? errCode : externErrCode); + GLOGE("Find item in source json object failed. %d", errCode); + return false; + } + bool ret = JsonNodeReplace(src, itemPath, father, item, externErrCode); + if (!ret) { + return false; + } + return false; + } else { + if (isReplace) { + GLOGE("path not exist, replace failed"); + externErrCode = -E_NO_DATA; + return false; + } + return JsonNodeAppend(src, path, father, item, externErrCode); + } + }); + return externErrCode; +} + +bool JsonCommon::isValueEqual(const ValueObject &srcValue, const ValueObject &targetValue) +{ + if (srcValue.GetValueType() == targetValue.GetValueType()) { + switch (srcValue.GetValueType()) { + case ValueObject::ValueType::VALUE_NULL: + return true; + case ValueObject::ValueType::VALUE_BOOL: + return srcValue.GetBoolValue() == targetValue.GetBoolValue(); + case ValueObject::ValueType::VALUE_NUMBER: + return srcValue.GetDoubleValue() == targetValue.GetDoubleValue(); + case ValueObject::ValueType::VALUE_STRING: + return srcValue.GetStringValue() == targetValue.GetStringValue(); + } + } + return false; +} + +bool JsonCommon::IsArrayMatch(const JsonObject &src, const JsonObject &target, int &isAlreadyMatched) +{ + JsonObject srcChild = src.GetChild(); + JsonObject targetObj = target; + bool isMatch = false; + int errCode = E_OK; + while (!srcChild.IsNull()) { + if (srcChild.GetType() == JsonObject::Type::JSON_OBJECT && target.GetType() == JsonObject::Type::JSON_OBJECT && + (IsJsonNodeMatch(srcChild, target, errCode))) { // The return value reflects the value of errCode + isMatch = true; + isAlreadyMatched = 1; + break; + } + srcChild = srcChild.GetNext(); + } + return isMatch; +} + +bool JsonCommon::IsObjectItemMatch(const JsonObject &srcItem, const JsonObject &item, int &isAlreadyMatched, + bool &isCollapse, int &isMatchFlag) +{ + if (srcItem.GetType() == JsonObject::Type::JSON_ARRAY && item.GetType() == JsonObject::Type::JSON_ARRAY && + !isAlreadyMatched) { + bool isEqual = (srcItem == item); + if (!isEqual) { // Filter value is No equal with src + isMatchFlag = isEqual; + } + isAlreadyMatched = isMatchFlag; + return false; // Both leaf node, no need iterate + } + if (srcItem.GetType() == JsonObject::Type::JSON_LEAF && item.GetType() == JsonObject::Type::JSON_LEAF && + !isAlreadyMatched) { + bool isEqual = isValueEqual(srcItem.GetItemValue(), item.GetItemValue()); + if (!isEqual) { // Filter value is No equal with src + isMatchFlag = isEqual; + } + isAlreadyMatched = isMatchFlag; + return false; // Both leaf node, no need iterate + } else if (srcItem.GetType() != item.GetType()) { + if (srcItem.GetType() == JsonObject::Type::JSON_ARRAY) { // srcItem Type is ARRAY, item Type is not ARRAY + bool isEqual = IsArrayMatch(srcItem, item, isAlreadyMatched); + if (!isEqual) { + isMatchFlag = isEqual; + } + return true; + } + isMatchFlag = false; + return false; // Different node types, overwrite directly, skip child node + } + return true; // Both array or object +} + +bool JsonCommon::JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, + bool &isCollapse, int &isMatchFlag) +{ + int errCode = E_OK; + JsonObject srcItem = src.FindItemPowerMode(itemPath, errCode); + if (errCode != -E_JSON_PATH_NOT_EXISTS && srcItem == item) { + isMatchFlag = true; + return false; + } + JsonFieldPath granpaPath = itemPath; + std::string lastFieldName = granpaPath.back(); + granpaPath.pop_back(); + JsonObject granpaItem = src.FindItemPowerMode(granpaPath, errCode); + if (errCode != -E_JSON_PATH_NOT_EXISTS && granpaItem.GetType() == JsonObject::Type::JSON_ARRAY && isCollapse) { + JsonObject fatherItem = granpaItem.GetChild(); + while (!fatherItem.IsNull()) { + if ((fatherItem.GetObjectItem(lastFieldName, errCode) == item)) { // this errCode is always E_OK + isMatchFlag = true; + break; + } + isMatchFlag = false; + fatherItem = fatherItem.GetNext(); + } + return false; + } + int isAlreadyMatched = 0; // means no match anything + return IsObjectItemMatch(srcItem, item, isAlreadyMatched, isCollapse, isMatchFlag); +} + +bool JsonCommon::IsJsonNodeMatch(const JsonObject &src, const JsonObject &target, int &errCode) +{ + errCode = E_OK; + int isMatchFlag = true; + JsonObjectIterator(target, {}, [&src, &isMatchFlag, &errCode](const JsonFieldPath &path, const JsonObject &item) { + int isAlreadyMatched = 0; + bool isCollapse = false; + if (isMatchFlag == false) { + return false; + } + JsonFieldPath itemPath = SplitePath(path, isCollapse); + if (src.IsFieldExistsPowerMode(itemPath)) { + if (isCollapse) { + return JsonEqualJudge(itemPath, src, item, isCollapse, isMatchFlag); + } else { + JsonObject srcItem = src.FindItemPowerMode(itemPath, errCode); + if (errCode != E_OK) { + return false; + } + if (srcItem.GetType() == JsonObject::Type::JSON_ARRAY) { + return JsonEqualJudge(itemPath, src, item, isCollapse, isMatchFlag); + } + if (srcItem == item) { + isMatchFlag = true; + isAlreadyMatched = true; + return false; + } + isMatchFlag = false; + return false; + } + } else { + std::vector ItemLeafValue = GetLeafValue(item); + for (auto ValueItem : ItemLeafValue) { + // filter leaf is null, Src leaf is dont exist. + if (ValueItem.GetValueType() == ValueObject::ValueType::VALUE_NULL) { + isMatchFlag = true; + return false; + } + } + if (isCollapse) { // Match failed, path not exist + isMatchFlag = false; + return false; + } + if (isAlreadyMatched == 0) { // Not match anything + isMatchFlag = false; + } + // Source path not exist, if leaf value is null, isMatchFlag become true, else it will become false. + return false; + } + }); + return isMatchFlag; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/log_print.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/log_print.cpp similarity index 80% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/log_print.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/log_print.cpp index 10fd0fffb8ed44bd2d8ca63ee51291932e5107a4..398dbc33173e530a338a2170c896e14cf809eb1d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/log_print.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/log_print.cpp @@ -14,33 +14,33 @@ */ #include -#include "securec.h" + #include "hilog/log.h" +#include "securec.h" namespace DocumentDB { namespace { - -void PrintLog(Logger::Level level, const std::string &tag, const std::string &msg) +void PrintLog(LogPrint::Level level, const char *tag, const std::string &msg) { if (msg.empty()) { return; } const std::string format = "%{public}s"; - OHOS::HiviewDFX::HiLogLabel label = { LOG_CORE, 0xD001630, tag.c_str() }; // log module id. // TODO: + OHOS::HiviewDFX::HiLogLabel label = { LOG_CORE, 0xD001631, tag }; // 0xD001631 is identity of the log switch (level) { - case Logger::Level::LEVEL_DEBUG: + case LogPrint::Level::LEVEL_DEBUG: (void)OHOS::HiviewDFX::HiLog::Debug(label, format.c_str(), msg.c_str()); break; - case Logger::Level::LEVEL_INFO: + case LogPrint::Level::LEVEL_INFO: (void)OHOS::HiviewDFX::HiLog::Info(label, format.c_str(), msg.c_str()); break; - case Logger::Level::LEVEL_WARN: + case LogPrint::Level::LEVEL_WARN: (void)OHOS::HiviewDFX::HiLog::Warn(label, format.c_str(), msg.c_str()); break; - case Logger::Level::LEVEL_ERROR: + case LogPrint::Level::LEVEL_ERROR: (void)OHOS::HiviewDFX::HiLog::Error(label, format.c_str(), msg.c_str()); break; - case Logger::Level::LEVEL_FATAL: + case LogPrint::Level::LEVEL_FATAL: (void)OHOS::HiviewDFX::HiLog::Fatal(label, format.c_str(), msg.c_str()); break; default: @@ -57,9 +57,9 @@ void PreparePrivateLog(const char *format, std::string &outStrFormat) outStrFormat.replace(pos, PRIVATE_TAG.size(), ".3s"); } } -} +} // namespace -void Logger::Log(Level level, const std::string &tag, const char *func, int line, const char *format, ...) +void LogPrint::Log(Level level, const char *tag, const char *format, ...) { static const int maxLogLength = 1024; @@ -79,4 +79,4 @@ void Logger::Log(Level level, const std::string &tag, const char *func, int line PrintLog(level, tag, msg); } -} +} // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/os_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp similarity index 83% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/os_api.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp index 31786a74dc86d85b77434dd791b98619996af373..8374915d78292a97c1f1988ae7b563c30797407c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/os_api.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/os_api.cpp @@ -13,9 +13,10 @@ * limitations under the License. */ #include "os_api.h" + +#include #include #include -#include #include "doc_errno.h" #include "log_print.h" @@ -23,7 +24,7 @@ namespace DocumentDB { namespace { - const int ACCESS_MODE_EXISTENCE = 0; +const int ACCESS_MODE_EXISTENCE = 0; } namespace OSAPI { bool CheckPermission(const std::string &filePath) @@ -39,7 +40,7 @@ bool CheckPathExistence(const std::string &filePath) int GetRealPath(const std::string &inOriPath, std::string &outRealPath) { const unsigned int MAX_PATH_LENGTH = PATH_MAX; - if (inOriPath.length() > MAX_PATH_LENGTH || MAX_PATH_LENGTH > 0x10000) { // max limit is 64K(0x10000). + if (inOriPath.length() > MAX_PATH_LENGTH) { // max limit is 64K(0x10000). GLOGE("[OS_API] OriPath too long."); return -E_INVALID_ARGS; } @@ -49,21 +50,21 @@ int GetRealPath(const std::string &inOriPath, std::string &outRealPath) return -E_OUT_OF_MEMORY; } if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) { - delete []realPath; + delete[] realPath; return -E_SECUREC_ERROR; } if (realpath(inOriPath.c_str(), realPath) == nullptr) { GLOGE("[OS_API] Realpath error:%d.", errno); - delete []realPath; + delete[] realPath; return -E_SYSTEM_API_FAIL; } outRealPath = std::string(realPath); - delete []realPath; + delete[] realPath; return E_OK; } -void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName) +void SplitFilePath(const std::string &filePath, std::string &fieldir, std::string &fileName) { if (filePath.empty()) { return; @@ -72,13 +73,12 @@ void SplitFilePath(const std::string &filePath, std::string &fileDir, std::strin auto slashPos = filePath.find_last_of('/'); if (slashPos == std::string::npos) { fileName = filePath; - fileDir = ""; + fieldir = ""; return; } - fileDir = filePath.substr(0, slashPos); + fieldir = filePath.substr(0, slashPos); fileName = filePath.substr(slashPos + 1); - return; } } // namespace OSAPI } // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/base/grd_db_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp similarity index 72% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/base/grd_db_api.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp index e6c954e339ba961dc628a31631de76c587d56ab8..f61b9ffc616a6ab4f2288087a7f2ff124cd97cd4 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/base/grd_db_api.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/base/grd_db_api.cpp @@ -17,16 +17,15 @@ #include "doc_errno.h" #include "document_store_manager.h" -#include "document_store.h" #include "grd_base/grd_error.h" #include "grd_type_inner.h" #include "log_print.h" using namespace DocumentDB; -int GRD_DBOpen(const char *dbPath, const char *configStr, unsigned int flags, GRD_DB **db) +GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db) { - if (db == nullptr || (*db) != nullptr) { + if (db == nullptr) { return GRD_INVALID_ARGS; } std::string path = (dbPath == nullptr ? "" : dbPath); @@ -34,21 +33,21 @@ int GRD_DBOpen(const char *dbPath, const char *configStr, unsigned int flags, GR DocumentStore *store = nullptr; int ret = DocumentStoreManager::GetDocumentStore(path, config, flags, store); if (ret != E_OK || store == nullptr) { - return TrasnferDocErr(ret); + return TransferDocErr(ret); } *db = new (std::nothrow) GRD_DB(); if (*db == nullptr) { (void)DocumentStoreManager::CloseDocumentStore(store, GRD_DB_CLOSE_IGNORE_ERROR); store = nullptr; - ret = -E_OUT_OF_MEMORY; + return GRD_FAILED_MEMORY_ALLOCATE; } (*db)->store_ = store; - return TrasnferDocErr(ret); + return TransferDocErr(ret); } -int GRD_DBClose(GRD_DB *db, unsigned int flags) +GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags) { if (db == nullptr || db->store_ == nullptr) { return GRD_INVALID_ARGS; @@ -56,10 +55,21 @@ int GRD_DBClose(GRD_DB *db, unsigned int flags) int ret = DocumentStoreManager::CloseDocumentStore(db->store_, flags); if (ret != E_OK) { - return TrasnferDocErr(ret); + return TransferDocErr(ret); } db->store_ = nullptr; delete db; return GRD_OK; } + +GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags) +{ + if (db == nullptr || db->store_ == nullptr) { + return GRD_INVALID_ARGS; + } + if (flags != GRD_DB_FLUSH_ASYNC && flags != GRD_DB_FLUSH_SYNC) { + return GRD_INVALID_ARGS; + } + return GRD_OK; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8b17915985e9a29cde9706665278d851f0978ad3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp @@ -0,0 +1,233 @@ +/* + * 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 +#include + +#include "doc_errno.h" +#include "log_print.h" +#include "securec.h" + +namespace DocumentDB { +namespace { +constexpr const char *KEY_ID = "_id"; +constexpr const char *COLLECTION_PREFIX_GRD = "GRD_"; +constexpr const char *COLLECTION_PREFIX_GM_SYS = "GM_SYS"; +const int MAX_COLLECTION_NAME = 512; +const int MAX_ID_LENS = 900; +const int JSON_DEEP_MAX = 4; + +bool CheckCollectionNamePrefix(const std::string &name, const std::string &prefix) +{ + if (name.length() < prefix.length()) { + return false; + } + + return (strncasecmp(name.c_str(), prefix.c_str(), prefix.length()) == 0); +} + +void ReplaceAll(std::string &inout, const std::string &what, const std::string &with) +{ + 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(); + } +} +} // namespace + +bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::string &formattedName, int &errCode) +{ + if (collectionName.empty()) { + errCode = -E_INVALID_ARGS; + return false; + } + if (collectionName.length() + 1 > MAX_COLLECTION_NAME) { // with '\0' + errCode = -E_OVER_LIMIT; + return false; + } + if (CheckCollectionNamePrefix(collectionName, COLLECTION_PREFIX_GRD) || + CheckCollectionNamePrefix(collectionName, COLLECTION_PREFIX_GM_SYS)) { + GLOGE("Collection name is illegal"); + errCode = -E_INVALID_COLL_NAME_FORMAT; + return false; + } + + formattedName = collectionName; + std::transform(formattedName.begin(), formattedName.end(), formattedName.begin(), [](unsigned char c) { + return std::tolower(c); + }); + + ReplaceAll(formattedName, "'", R"('')"); + return true; +} + +int CheckCommon::CheckFilter(JsonObject &filterObj, std::vector> &filterPath, bool &isIdExist) +{ + for (size_t i = 0; i < filterPath.size(); i++) { + if (filterPath[i].size() > JSON_DEEP_MAX) { + GLOGE("filter's json deep is deeper than JSON_DEEP_MAX"); + return -E_INVALID_ARGS; + } + } + for (size_t i = 0; i < filterPath.size(); i++) { + if (filterPath[i].empty()) { + return -E_INVALID_JSON_FORMAT; + } + for (size_t j = 0; j < filterPath[i].size(); j++) { + if (filterPath[i][j].empty()) { + return -E_INVALID_ARGS; + } + for (auto oneChar : filterPath[i][j]) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return -E_INVALID_ARGS; + } + } + } + if (!filterPath[i].empty() && !filterPath[i][0].empty() && isdigit(filterPath[i][0][0])) { + return -E_INVALID_ARGS; + } + } + int ret = CheckIdFormat(filterObj, isIdExist); + if (ret != E_OK) { + GLOGE("Filter Id format is illegal"); + return ret; + } + return E_OK; +} + +int CheckCommon::CheckIdFormat(JsonObject &filterJson, bool &isIdExisit) +{ + JsonObject filterObjChild = filterJson.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExisit); + if ((idValue.GetValueType() == ValueObject::ValueType::VALUE_NULL) && isIdExisit == false) { + return E_OK; + } + if (idValue.GetValueType() != ValueObject::ValueType::VALUE_STRING) { + return -E_INVALID_ARGS; + } + if (idValue.GetStringValue().length() + 1 > MAX_ID_LENS) { // with '\0' + return -E_OVER_LIMIT; + } + return E_OK; +} + +int CheckCommon::CheckDocument(JsonObject &documentObj, bool &isIdExist) +{ + if (documentObj.GetDeep() > JSON_DEEP_MAX) { + GLOGE("documentObj's json deep is deeper than JSON_DEEP_MAX"); + return -E_INVALID_ARGS; + } + int ret = CheckIdFormat(documentObj, isIdExist); + if (ret != E_OK) { + return ret; + } + JsonObject documentObjChild = documentObj.GetChild(); + if (!JsonCommon::CheckJsonField(documentObjChild)) { + GLOGE("Document json field format is illegal"); + return -E_INVALID_ARGS; + } + return E_OK; +} + +int SplitFieldName(const std::string &fieldName, std::vector &allFieldsName) +{ + std::string tempParseName; + std::string priFieldName = fieldName; + for (size_t j = 0; j < priFieldName.size(); j++) { + if (priFieldName[j] != '.') { + tempParseName += priFieldName[j]; + } + if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { + if ((j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') || + (priFieldName[j] == '.' && j == priFieldName.size() - 1)) { + return -E_INVALID_ARGS; + } + allFieldsName.emplace_back(tempParseName); + tempParseName.clear(); + } + } + return E_OK; +} + +int CheckCommon::CheckUpdata(JsonObject &updataObj) +{ + JsonObject jsonTemp = updataObj.GetChild(); + size_t maxDeep = 0; + while (!jsonTemp.IsNull()) { + std::vector allFieldsName; + int errCode = SplitFieldName(jsonTemp.GetItemField(), allFieldsName); + 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; + } + } + } + maxDeep = std::max(allFieldsName.size() + jsonTemp.GetDeep(), maxDeep); + if (maxDeep > JSON_DEEP_MAX) { + GLOGE("document's json deep is deeper than JSON_DEEP_MAX"); + return -E_INVALID_ARGS; + } + jsonTemp = jsonTemp.GetNext(); + } + bool isIdExist = true; + CheckIdFormat(updataObj, isIdExist); + if (isIdExist) { + return -E_INVALID_ARGS; + } + return E_OK; +} + +int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &path) +{ + if (projectionObj.GetDeep() > JSON_DEEP_MAX) { + GLOGE("projectionObj's json deep is deeper than JSON_DEEP_MAX"); + return -E_INVALID_ARGS; + } + int errCode = E_OK; + if (!projectionObj.GetChild().IsNull()) { + JsonObject projectionObjChild = projectionObj.GetChild(); + if (!JsonCommon::CheckProjectionField(projectionObjChild, errCode)) { + GLOGE("projection json field format is illegal"); + return errCode; + } + } + for (size_t i = 0; i < path.size(); i++) { + if (path[i].empty()) { + return -E_INVALID_JSON_FORMAT; + } + for (const auto &fieldName : path[i]) { + 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; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h similarity index 59% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_common.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h index a0ebfaee4eedf370bc1e0542abcc15279c08e6ab..3ace41987600724d0deb5e1a0dd9d3e5a1643525 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/doc_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.h @@ -13,29 +13,29 @@ * limitations under the License. */ -#ifndef DOC_COMMON_H -#define DOC_COMMON_H +#ifndef CHECK_COMMON_H +#define CHECK_COMMON_H #include #include + #include "json_common.h" namespace DocumentDB { class JsonCommon; -class CheckCommon -{ +class CheckCommon { public: - CheckCommon() = default; + CheckCommon() = delete; ~CheckCommon() = default; - static bool CheckCollectionName(const std::string &collectionName, std::string &lowerCaseName, int &errCode); - static bool CheckFilter(const std::string &filter); - static bool CheckIdFormat(const std::string &data); - static bool CheckDocument(const std::string &document); + static bool CheckCollectionName(const std::string &collectionName, std::string &formattedName, int &errCode); + static int CheckFilter(JsonObject &document, std::vector> &filterPath, bool &isIdExist); + static int CheckIdFormat(JsonObject &data, bool &isIdExisit); + static int CheckDocument(JsonObject &document, bool &isIdExist); + static int CheckUpdata(JsonObject &updataObj); + static int CheckProjection(JsonObject &projectionObj, std::vector> &path); }; using Key = std::vector; using Value = std::vector; - -constexpr const char *COLL_PREFIX = "GRD_COLL_"; -} // DocumentDB -#endif // DOC_COMMON_H \ No newline at end of file +} // namespace DocumentDB +#endif // CHECK_COMMON_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp new file mode 100644 index 0000000000000000000000000000000000000000..701ad17e7bad1919971fb7b22873276b683a7d0e --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_document_api.cpp @@ -0,0 +1,119 @@ +/* +* 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 "grd_base/grd_error.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) +{ + if (db == nullptr || db->store_ == nullptr) { + return GRD_INVALID_ARGS; + } + + std::string name = (collectionName == nullptr ? "" : collectionName); + std::string option = (optionStr == nullptr ? "" : optionStr); + int ret = db->store_->CreateCollection(name, option, flags); + return TransferDocErr(ret); +} + +GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint32_t flags) +{ + if (db == nullptr || db->store_ == nullptr) { + return GRD_INVALID_ARGS; + } + + std::string name = (collectionName == nullptr ? "" : collectionName); + int ret = db->store_->DropCollection(name, flags); + return TransferDocErr(ret); +} + +GRD_API int32_t GRD_UpdateDoc(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) { + return GRD_INVALID_ARGS; + } + int ret = db->store_->UpdateDocument(collectionName, filter, update, flags); + if (ret >= 0) { + return ret; + } + return TransferDocErr(ret); +} + +GRD_API int32_t GRD_UpsertDoc(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 || + document == nullptr) { + return GRD_INVALID_ARGS; + } + int ret = db->store_->UpsertDocument(collectionName, filter, document, flags); + if (ret >= 0) { + return ret; + } + return TransferDocErr(ret); +} + +GRD_API int32_t GRD_InsertDoc(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; + } + int ret = db->store_->InsertDocument(collectionName, document, flags); + return TransferDocErr(ret); +} + +GRD_API int32_t GRD_DeleteDoc(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; + } + int ret = db->store_->DeleteDocument(collectionName, filter, flags); + int errCode = TransferDocErr(ret); + switch (errCode) { + case GRD_OK: + return 1; // The amount of text deleted + case GRD_NO_DATA: + return 0; + default: + return errCode; + } +} + +GRD_API int32_t GRD_FindDoc(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) { + return GRD_INVALID_ARGS; + } + GRD_ResultSet *grdResultSet = new (std::nothrow) GRD_ResultSet(); + if (grdResultSet == nullptr) { + GLOGE("Memory allocation failed!"); + return -E_FAILED_MEMORY_ALLOCATE; + } + int ret = db->store_->FindDocument(collectionName, query.filter, query.projection, flags, grdResultSet); + if (ret != E_OK) { + delete grdResultSet; + return TransferDocErr(ret); + } + *resultSet = grdResultSet; + return TransferDocErr(ret); +} diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp similarity index 32% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp index 61f50633eb9f8452b0624bb6a4641330316f9288..d529552f9d1bacaefe7803050d14a6fd90b4817b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/grd_resultset_api.cpp @@ -12,58 +12,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "grd_base/grd_resultset_api.h" -#include "grd_document/grd_document_api.h" +#include + +#include "doc_errno.h" #include "grd_base/grd_error.h" -#include "grd_type_inner.h" +#include "grd_resultset_inner.h" #include "log_print.h" + using namespace DocumentDB; -int GRD_CreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, unsigned int flags) +GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet) { - if (db == nullptr || db->store_ == nullptr) { + if (resultSet == nullptr) { + GLOGE("resultSet is nullptr"); return GRD_INVALID_ARGS; - } - - std::string name = (collectionName == nullptr ? "" : collectionName); - std::string option = (optionStr == nullptr ? "" : optionStr); - int ret = db->store_->CreateCollection(name, option, flags); - return TrasnferDocErr(ret); + }; + int ret = resultSet->resultSet_.GetNext(true, true); + return TransferDocErr(ret); } -int GRD_DropCollection(GRD_DB *db, const char *collectionName, unsigned int flags) +GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value) { - if (db == nullptr || db->store_ == nullptr) { + if (resultSet == nullptr || value == nullptr) { + GLOGE("resultSet is nullptr,cant get value from it"); return GRD_INVALID_ARGS; + }; + char *val = nullptr; + int ret = resultSet->resultSet_.GetValue(&val); + if (val == nullptr) { + GLOGE("Value that get from resultSet is nullptr"); + return GRD_NOT_AVAILABLE; } - - std::string name = (collectionName == nullptr ? "" : collectionName); - int ret = db->store_->DropCollection(name, flags); - return TrasnferDocErr(ret); + *value = val; + return TransferDocErr(ret); } -int GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *update, unsigned int flags) +GRD_API int32_t GRD_FreeValue(char *value) { - if (db == nullptr || db->store_ == nullptr) { + if (value == nullptr) { return GRD_INVALID_ARGS; } - - std::string name = (collectionName == nullptr ? "" : collectionName); - std::string filterStr = (filter == nullptr ? "" : filter); - std::string updateStr = (update == nullptr ? "" : update); - int ret = db->store_->UpdateDocument(name, filterStr, updateStr, flags); - return TrasnferDocErr(ret); + delete[] value; + return GRD_OK; } -int GRD_UpSertDoc(GRD_DB *db, const char *collectionName, const char *filter, const char *document, unsigned int flags) +GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet) { - if (db == nullptr || db->store_ == nullptr) { + if (resultSet == nullptr) { return GRD_INVALID_ARGS; } - - std::string name = (collectionName == nullptr ? "" : collectionName); - std::string filterStr = (filter == nullptr ? "" : filter); - std::string documentStr = (document == nullptr ? "" : document); - int ret = db->store_->UpsertDocument(name, filterStr, documentStr, flags); - return TrasnferDocErr(ret); -} + resultSet->resultSet_.EraseCollection(); + delete resultSet; + return GRD_OK; +} \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_format_config.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_format_config.h new file mode 100644 index 0000000000000000000000000000000000000000..f4a546821718fdc4de84120c60675f5da2b5b7f5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_format_config.h @@ -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. +*/ + +#ifndef GRD_FORMAT_CONFIG_H +#define GRD_FORMAT_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define COLLECTION_LENS_MAX (512 * 1024) +#define JSON_LENS_MAX (1024 * 1024) +#define JSON_DEEP_MAX (4) +#define KEY_ID ("_id") + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // GRD_FORMAT_CONFIG_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_resultset_inner.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_resultset_inner.h new file mode 100644 index 0000000000000000000000000000000000000000..d840ad79370a4cca20b76e5ed877aadde6d1eda8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_resultset_inner.h @@ -0,0 +1,26 @@ +/* +* 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_INNER_H +#define GRD_RESULTSET_INNER_H + +#include "doc_errno.h" +#include "grd_base/grd_error.h" +#include "result_set.h" + +typedef struct GRD_ResultSet { + DocumentDB::ResultSet resultSet_; +} GRD_ResultSet; +#endif // GRD_RESULTSET_INNER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/include/grd_type_inner.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_type_inner.h similarity index 100% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/include/grd_type_inner.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_type_inner.h index 6366370136761013c6cbeaa4dd65214df36cfcf6..f26f6ac4897e2a80b7f347844a775f78208346a4 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/include/grd_type_inner.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/include/grd_type_inner.h @@ -16,8 +16,8 @@ #ifndef GRD_TYPE_INNER_H #define GRD_TYPE_INNER_H -#include "document_store.h" #include "doc_errno.h" +#include "document_store.h" #include "grd_base/grd_error.h" typedef struct GRD_DB { diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h similarity index 63% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h index b71feaae45a66196a305e3cc6e8e11800b8f0c2d..30d109eda401489efb6fed1ade829869290271bc 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h @@ -17,7 +17,8 @@ #define COLLECTION_H #include -#include "doc_common.h" + +#include "check_common.h" #include "kv_store_executor.h" namespace DocumentDB { @@ -26,13 +27,17 @@ public: Collection(const std::string &name, KvStoreExecutor *executor); ~Collection(); - int PutDocument(const Key &key, const Value &document); - int GetDocument(const Key &key, Value &document) const; - int DeleteDocument(const Key &key); + int InsertDocument(const std::string &id, const std::string &document, bool &isIdExist); + int GetDocumentById(Key &key, Value &document) const; + int GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const; + int DeleteDocument(Key &key); + int IsCollectionExists(int &errCode); + int UpsertDocument(const std::string &id, const std::string &newDocument, bool &isIdExist); + int UpdateDocument(const std::string &id, const std::string &document); - int UpsertDocument(const std::string &id, const std::string &document, bool isReplace = true); - int UpdateDocument(const Key &key, Value &update); private: + int InsertUntilSuccess(Key &key, const std::string &id, Value &valSet); std::string name_; KvStoreExecutor *executor_ = nullptr; }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/doc_errno.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h similarity index 80% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/doc_errno.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h index 6c80c6936da3636e0126063426aa8debea05bf28..75f636b55da36eeec89ec0476e85807df1c99e9f 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/doc_errno.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h @@ -33,10 +33,15 @@ constexpr int E_COLLECTION_CONFLICT = E_BASE + 15; constexpr int E_NO_DATA = E_BASE + 16; constexpr int E_NOT_PERMIT = E_BASE + 17; constexpr int E_DATA_CONFLICT = E_BASE + 18; -constexpr int E_INVALID_COLL_NAME_FORMAT = E_BASE + 18; +constexpr int E_INVALID_COLL_NAME_FORMAT = E_BASE + 19; constexpr int E_INVALID_JSON_FORMAT = E_BASE + 40; constexpr int E_JSON_PATH_NOT_EXISTS = E_BASE + 41; +constexpr int E_RESOURCE_BUSY = E_BASE + 50; +constexpr int E_FAILED_MEMORY_ALLOCATE = E_BASE + 51; +constexpr int E_INNER_ERROR = E_BASE + 52; +constexpr int E_INVALID_FILE_FORMAT = E_BASE + 53; +constexpr int E_FAILED_FILE_OPERATION = E_BASE + 54; -int TrasnferDocErr(int err); -} // DocumentDB +int TransferDocErr(int err); +} // namespace DocumentDB #endif // DOC_ERRNO_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h new file mode 100644 index 0000000000000000000000000000000000000000..32dbd79e8b7b13ee9d8c8adc8b0d70a4def3432e --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h @@ -0,0 +1,48 @@ +/* +* 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 DOCUMENT_KEY_H +#define DOCUMENT_KEY_H + +#include +#include + +#include "json_object.h" + +#define GRD_DOC_OID_TIME_SIZE 4 +#define GRD_DOC_OID_INCREMENTAL_VALUE_SIZE 2 +#define GRD_DOC_OID_SIZE (GRD_DOC_OID_TIME_SIZE + GRD_DOC_OID_INCREMENTAL_VALUE_SIZE) +#define GRD_DOC_OID_HEX_SIZE (GRD_DOC_OID_SIZE * 2) +#define GRD_DOC_ID_TYPE_SIZE 1 + +namespace DocumentDB { +enum class DocIdType { + INT = 1, + STRING, +}; + +struct DocKey { +public: + int32_t keySize; + std::string key; + uint8_t type; +}; + +class DocumentKey { +public: + static int GetOidDocKey(DocKey &key); +}; +} // namespace DocumentDB +#endif // DOCUMENT_KEY_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h new file mode 100644 index 0000000000000000000000000000000000000000..3f1deacb9279377a9e1f689672beeed5a83dd38e --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h @@ -0,0 +1,83 @@ +/* +* 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 DOCUMENT_STORE_H +#define DOCUMENT_STORE_H + +#include +#include +#include + +#include "collection.h" +#include "document_type.h" +#include "kv_store_executor.h" + +struct GRD_ResultSet; +namespace DocumentDB { +class DocumentStore { +public: + DocumentStore(KvStoreExecutor *); + ~DocumentStore(); + + int CreateCollection(const std::string &name, const std::string &option, uint32_t flags); + + int DropCollection(const std::string &name, uint32_t flags); + + int UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, + uint32_t flags); + + int UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, + uint32_t flags); + + int InsertDocument(const std::string &collection, const std::string &document, uint32_t flags); + + int DeleteDocument(const std::string &collection, const std::string &filter, uint32_t flags); + + int FindDocument(const std::string &collection, const std::string &filter, const std::string &projection, + uint32_t flags, GRD_ResultSet *grdResultSet); + + Collection GetCollection(std::string &collectionName); + + bool IsExistResultSet(const std::string &collection); + + int EraseCollection(const std::string &collectionName); + + void OnClose(const std::function ¬ifier); + + int Close(uint32_t flags); + + int StartTransaction(); + int Commit(); + int Rollback(); + + bool IsCollectionExists(const std::string &collectionName, int &errCode); + + std::mutex dbMutex_; + +private: + int UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, + bool &isReplace); + int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &document, + JsonObject &documentObj, bool &isReplace); + int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj, + bool &isIdExist); + int DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj); + int InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context); + KvStoreExecutor *executor_ = nullptr; + std::map collections_; + std::function closeNotifier_; +}; +} // namespace DocumentDB +#endif // DOCUMENT_STORE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store_manager.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store_manager.h similarity index 72% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store_manager.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store_manager.h index 7004316297c97f6d592863672b892e29d6c9a8f8..f9745fae8f50083eec9824bfaee574ae2ceb5bcf 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store_manager.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store_manager.h @@ -16,20 +16,24 @@ #ifndef DOCUMENT_STORE_MANAGER_H #define DOCUMENT_STORE_MANAGER_H +#include #include + #include "document_store.h" namespace DocumentDB { class DocumentStoreManager { public: - static int GetDocumentStore(const std::string &path, const std::string &config, unsigned int flags, + static int GetDocumentStore(const std::string &path, const std::string &config, uint32_t flags, DocumentStore *&store); - static int CloseDocumentStore(DocumentStore *store, unsigned int flags); + static int CloseDocumentStore(DocumentStore *store, uint32_t flags); private: - static bool CheckDBPath(const std::string &path, std::string &canonicalPath, std::string &dbName, int &errCode); - static bool CheckDBConfig(const std::string &config, int &errCode); + static int CheckDBPath(const std::string &path, std::string &canonicalPath, std::string &dbName); + + static std::mutex openCloseMutex_; + static std::map dbConnCount_; }; -} // DocumentDB +} // namespace DocumentDB #endif // DOCUMENT_STORE_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h similarity index 44% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h index b1fa3c39ae693e125d3fb8c846ba299d82f953b8..3cdca06d33f336618a322849ce910432fb6a2aea 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h @@ -12,34 +12,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef PROJECTION_TREE_H +#define PROJECTION_TREE_H -#ifndef DOCUMENT_STORE_H -#define DOCUMENT_STORE_H +#include +#include +#include -#include -#include -#include - -#include "collection.h" -#include "kv_store_executor.h" +#include "doc_errno.h" +#include "json_common.h" +#include "log_print.h" namespace DocumentDB { -class DocumentStore { +struct ProjectionNode { + std::unordered_map sonNode; + bool isDeepest; + int Deep; + ProjectionNode() + { + Deep = 0; + isDeepest = true; + } + int DeleteProjectionNode(); + ~ProjectionNode() + { + DeleteProjectionNode(); + } +}; +class ProjectionTree { public: - DocumentStore(KvStoreExecutor *); - ~DocumentStore(); - - int CreateCollection(const std::string &name, const std::string &option, int flags); - int DropCollection(const std::string &name, int flags); - - int UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, int flag); - int UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, int flags); + int ParseTree(std::vector> &path); + bool SearchTree(std::vector &singlePath, size_t &index); private: - std::mutex dbMutex_; - - KvStoreExecutor *executor_ = nullptr; - std::map collections_; + ProjectionNode node_; }; -} // DocumentDB -#endif // DOCUMENT_STORE_H \ No newline at end of file +} // namespace DocumentDB +#endif // PROJECTION_TREE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h new file mode 100644 index 0000000000000000000000000000000000000000..01c42c63e52940b26a1eac9f54caf45fdb01252c --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h @@ -0,0 +1,57 @@ +/* +* 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 RESULTSET_H +#define RESULTSET_H + +#include +#include +#include + +#include "check_common.h" +#include "doc_errno.h" +#include "document_store.h" +#include "grd_base/grd_type_export.h" +#include "json_object.h" + +namespace DocumentDB { +class ResultSet { +public: + ResultSet(); + ~ResultSet(); + int Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch); + int GetNext(bool isNeedTransaction = false, bool isNeedCheckTable = false); + int GetValue(char **value); + int GetValue(std::string &value); + int GetKey(std::string &key); + int EraseCollection(); + +private: + int GetNextInner(bool isNeedCheckTable); + int GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData); + int CutJsonBranch(std::string &jsonKey, std::string &jsonData); + int CheckCutNode(JsonObject *node, std::vector singleCutPath, + std::vector> &allCutPath); + int GetNextWithField(); + + DocumentStore *store_ = nullptr; + bool isCutBranch_ = false; + size_t index_ = 0; + std::shared_ptr context_; + std::pair matchData_; + std::string lastKeyIndex_; +}; +} // namespace DocumentDB +#endif // RESULTSET_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h new file mode 100644 index 0000000000000000000000000000000000000000..abdf5c9b3ce66af2c112ed19fc54bb3fec633915 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h @@ -0,0 +1,30 @@ +/* +* 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 RESULTSET_COMMON_H +#define RESULTSET_COMMON_H + +#include + +#include "doc_errno.h" +#include "grd_base/grd_type_export.h" +#include "result_set.h" +#include "vector" + +namespace DocumentDB { +class ValueObject; +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch); +} // namespace DocumentDB +#endif // RESULTSET_COMMON_H diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp similarity index 38% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp index d04eb8022ac7fb77f4fb400d1fe0eca2251340d4..d06b0943d59c0519231b5f7c03481cf405b1a479 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp @@ -15,10 +15,10 @@ #include "collection.h" -#include - -#include "doc_common.h" +#include "check_common.h" +#include "db_constant.h" #include "doc_errno.h" +#include "document_key.h" #include "log_print.h" namespace DocumentDB { @@ -28,7 +28,7 @@ Collection::Collection(const std::string &name, KvStoreExecutor *executor) : exe std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { return std::tolower(c); }); - name_ = COLL_PREFIX + lowerCaseName; + name_ = DBConstant::COLL_PREFIX + lowerCaseName; } Collection::~Collection() @@ -36,30 +36,83 @@ Collection::~Collection() executor_ = nullptr; } -int Collection::PutDocument(const Key &key, const Value &document) +int Collection::InsertUntilSuccess(Key &key, const std::string &id, Value &valSet) +{ + DocKey docKey; + key.assign(id.begin(), id.end()); + int errCode = executor_->InsertData(name_, key, valSet); + while (errCode == -E_DATA_CONFLICT) { // if id alreay exist, create new one. + DocumentKey::GetOidDocKey(docKey); + key.assign(docKey.key.begin(), docKey.key.end()); + errCode = executor_->InsertData(name_, key, valSet); + } + return errCode; +} +int Collection::InsertDocument(const std::string &id, const std::string &document, bool &isIdExist) { if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + int errCode = E_OK; + bool isCollectionExist = IsCollectionExists(errCode); + if (errCode != E_OK) { + return errCode; + } + if (!isCollectionExist) { return -E_INVALID_ARGS; } - return executor_->PutData(name_, key, document); + Key key; + Value valSet(document.begin(), document.end()); + if (!isIdExist) { + return InsertUntilSuccess(key, id, valSet); + } + key.assign(id.begin(), id.end()); + return executor_->InsertData(name_, key, valSet); } -int Collection::GetDocument(const Key &key, Value &document) const +int Collection::GetDocumentById(Key &key, Value &document) const { - return E_OK; + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->GetDataById(name_, key, document); } -int Collection::DeleteDocument(const Key &key) +int Collection::GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const { - return E_OK; + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->GetDataByFilter(name_, key, filterObj, values, isIdExist); } -int Collection::UpsertDocument(const std::string &id, const std::string &document, bool isReplace) +int Collection::DeleteDocument(Key &key) { if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + int errCode = E_OK; + bool isCollectionExist = IsCollectionExists(errCode); + if (errCode != E_OK) { + return errCode; + } + if (!isCollectionExist) { return -E_INVALID_ARGS; } + return executor_->DelData(name_, key); +} + +int Collection::IsCollectionExists(int &errCode) +{ + return executor_->IsCollectionExists(name_, errCode); +} +int Collection::UpsertDocument(const std::string &id, const std::string &newDocument, bool &isDataExist) +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } int errCode = E_OK; bool isCollExist = executor_->IsCollectionExists(name_, errCode); if (errCode != E_OK) { @@ -68,47 +121,34 @@ int Collection::UpsertDocument(const std::string &id, const std::string &documen } if (!isCollExist) { GLOGE("Collection not created."); - return -E_NO_DATA; + return -E_INVALID_ARGS; } + Key key; + Value valSet(newDocument.begin(), newDocument.end()); + if (!isDataExist) { + return InsertUntilSuccess(key, id, valSet); + } + key.assign(id.begin(), id.end()); + return executor_->PutData(name_, key, valSet); +} - JsonObject upsertValue = JsonObject::Parse(document, errCode); +int Collection::UpdateDocument(const std::string &id, const std::string &newDocument) +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + int errCode = E_OK; + bool isCollExist = executor_->IsCollectionExists(name_, errCode); if (errCode != E_OK) { - GLOGD("Parse upsert value failed. %d", errCode); - return errCode; + GLOGE("Check collection failed. %d", errCode); + return -errCode; } - - Key keyId(id.begin(), id.end()); - Value valSet(document.begin(), document.end()); - - if (!isReplace) { - Value valueGot; - errCode = executor_->GetData(name_, keyId, valueGot); - std::string valueGotStr = std::string(valueGot.begin(), valueGot.end()); - - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - GLOGE("Get original document failed. %d", errCode); - return errCode; - } else if (errCode == E_OK) { // document has been inserted - GLOGD("Document has been inserted, append value."); - JsonObject originValue = JsonObject::Parse(valueGotStr, errCode); - if (errCode != E_OK) { - GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); - return errCode; - } - - errCode = JsonCommon::Append(originValue, upsertValue); - if (errCode != E_OK) { - GLOGD("Append value failed. %d", errCode); - return errCode; - } - } + if (!isCollExist) { + GLOGE("Collection not created."); + return -E_INVALID_ARGS; } - + Key keyId(id.begin(), id.end()); + Value valSet(newDocument.begin(), newDocument.end()); return executor_->PutData(name_, keyId, valSet); } - -int Collection::UpdateDocument(const Key &key, Value &update) -{ - return E_OK; -} } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp similarity index 43% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp index 9cedce6ac0faa3c89e7949a3fb89f720e125aef3..bf9dca10b3fba2ae988d605ec65d609531dd49e9 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp @@ -14,55 +14,60 @@ */ #include "doc_errno.h" + #include "grd_base/grd_error.h" namespace DocumentDB { int GetErrorCategory(int errCode) { - int categoryCode = errCode % 1000000; - categoryCode /= 1000; - categoryCode *= 1000; + int categoryCode = errCode % 1000000; // 1000000: mod to get last 6 digits + categoryCode /= 1000; // 1000: deviced to remove first 3 digits + categoryCode *= 1000; // 1000: multiply to pad the output return categoryCode; } -int TrasnferDocErr(int err) +int TransferDocErr(int err) { - int outErr = GRD_OK; + if (err > 0) { + return err; + } + switch (err) { case E_OK: return GRD_OK; case -E_ERROR: - outErr = GRD_INNER_ERR; - break; + return GetErrorCategory(GRD_INNER_ERR); case -E_INVALID_ARGS: - outErr = GRD_INVALID_ARGS; - break; + return GetErrorCategory(GRD_INVALID_ARGS); case -E_FILE_OPERATION: - outErr = GRD_FAILED_FILE_OPERATION; - break; + return GetErrorCategory(GRD_FAILED_FILE_OPERATION); case -E_OVER_LIMIT: - outErr = GRD_OVER_LIMIT; - break; + return GetErrorCategory(GRD_OVER_LIMIT); case -E_INVALID_JSON_FORMAT: - outErr = GRD_INVALID_JSON_FORMAT; - break; + return GetErrorCategory(GRD_INVALID_JSON_FORMAT); case -E_INVALID_CONFIG_VALUE: - outErr = GRD_INVALID_CONFIG_VALUE; - break; + return GetErrorCategory(GRD_INVALID_CONFIG_VALUE); + case -E_DATA_CONFLICT: + return GetErrorCategory(GRD_DATA_CONFLICT); case -E_COLLECTION_CONFLICT: - outErr = GRD_COLLECTION_CONFLICT; - break; + return GetErrorCategory(GRD_COLLECTION_CONFLICT); case -E_NO_DATA: - outErr = GRD_NO_DATA; - break; + case -E_NOT_FOUND: + return GetErrorCategory(GRD_NO_DATA); case -E_INVALID_COLL_NAME_FORMAT: - outErr = GRD_INVALID_COLLECTION_NAME; - break; + return GetErrorCategory(GRD_INVALID_COLLECTION_NAME); + case -E_RESOURCE_BUSY: + return GetErrorCategory(GRD_RESOURCE_BUSY); + case -E_FAILED_MEMORY_ALLOCATE: + case -E_OUT_OF_MEMORY: + return GetErrorCategory(GRD_FAILED_MEMORY_ALLOCATE); + case -E_INVALID_FILE_FORMAT: + return GetErrorCategory(GRD_INVALID_FILE_FORMAT); + case -E_FAILED_FILE_OPERATION: + return GetErrorCategory(GRD_FAILED_FILE_OPERATION); + case -E_INNER_ERROR: default: - outErr = GRD_INNER_ERR; - break; + return GetErrorCategory(GRD_INNER_ERR); } - - return GetErrorCategory(outErr); } -} \ No newline at end of file +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp similarity index 38% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp index 7c0f0456d8f747dbaf9e74e51f0677ed35bc50c8..a64932053790730da79005afe7b18b385b8d5639 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp @@ -12,33 +12,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "document_key.h" -#ifndef JSON_COMMON_H -#define JSON_COMMON_H - -#include -#include -#include -#include "json_object.h" - +#include "doc_errno.h" +#include "log_print.h" +#include "securec.h" namespace DocumentDB { -class JsonCommon +static uint16_t g_oIdIncNum = 0; +constexpr uint16_t MAX_NUMBER_OF_AUTOINCREMENTS = 65535; +constexpr uint16_t UINT_ZERO = 0; +static int InitDocIdFromOid(DocKey &docKey) { -public: - JsonCommon() = default; - ~JsonCommon(); - - static ResultValue GetValueByFiled(JsonObject *node, const std::string& filed); - static bool CheckJsonField(const std::string &data); - static int ParseNode(JsonObject *Node, std::vector singlePath, std::vector> &resultPath, bool isFirstFloor); - static std::vector> ParsePath(const JsonObject* const node); - static std::vector GetLeafValue(JsonObject *node); + time_t nowTime = time(nullptr); + if (nowTime < 0) { + return -E_INNER_ERROR; + } + uint32_t now = (uint32_t)nowTime; + uint16_t iv = g_oIdIncNum++; + // The maximum number of autoincrements is 65535, and if it is exceeded, it becomes 0. + if (g_oIdIncNum > MAX_NUMBER_OF_AUTOINCREMENTS) { + g_oIdIncNum = UINT_ZERO; + } + char *idTemp = new char[GRD_DOC_OID_HEX_SIZE + 1]; + if (sprintf_s(idTemp, GRD_DOC_OID_HEX_SIZE + 1, "%08x%04x", now, iv) < 0) { + GLOGE("get oid error"); + return -E_INNER_ERROR; + } + docKey.key = idTemp; + delete[] idTemp; + return E_OK; +} - static int Append(const JsonObject &src, const JsonObject &add); - -private: - static bool CheckNode(JsonObject *Node, std::set filedSet, bool &errFlag); - static int CheckLeafNode(JsonObject *Node, std::vector &leafValue); -}; -} // DocumentDB -#endif // JSON_COMMON_H \ No newline at end of file +int DocumentKey::GetOidDocKey(DocKey &key) +{ + int ret = InitDocIdFromOid(key); + return ret; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe2d1ded4b75c70a510f38a8e7bb3c80bffbb702 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp @@ -0,0 +1,906 @@ +/* +* 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 "document_store.h" + +#include "check_common.h" +#include "collection_option.h" +#include "doc_errno.h" +#include "document_key.h" +#include "grd_base/grd_type_export.h" +#include "grd_resultset_inner.h" +#include "log_print.h" +#include "result_set.h" +#include "result_set_common.h" + +namespace DocumentDB { +constexpr int JSON_LENS_MAX = 1024 * 1024; +constexpr const char *KEY_ID = "_id"; + +DocumentStore::DocumentStore(KvStoreExecutor *executor) : executor_(executor) {} + +DocumentStore::~DocumentStore() +{ + delete executor_; +} + +int DocumentStore::CreateCollection(const std::string &name, const std::string &option, uint32_t flags) +{ + std::string lowerCaseName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(name, lowerCaseName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + errCode = E_OK; + CollectionOption collOption = CollectionOption::ReadOption(option, errCode); + if (errCode != E_OK) { + GLOGE("Read collection option str failed. %d", errCode); + return errCode; + } + + if (flags != 0u && flags != CHK_EXIST_COLLECTION) { + GLOGE("Check flags invalid."); + return -E_INVALID_ARGS; + } + + std::lock_guard lock(dbMutex_); + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + + std::string oriOptStr; + bool ignoreExists = (flags != CHK_EXIST_COLLECTION); + errCode = executor_->CreateCollection(lowerCaseName, oriOptStr, ignoreExists); + if (errCode != E_OK) { + GLOGE("Create collection failed. %d", errCode); + goto END; + } + +END: + if (errCode == E_OK) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return errCode; +} + +int DocumentStore::DropCollection(const std::string &name, uint32_t flags) +{ + std::string lowerCaseName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(name, lowerCaseName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + + if (flags != 0u && flags != CHK_NON_EXIST_COLLECTION) { + GLOGE("Check flags invalid."); + return -E_INVALID_ARGS; + } + + bool ignoreNonExists = (flags != CHK_NON_EXIST_COLLECTION); + std::lock_guard lock(dbMutex_); + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + + errCode = executor_->DropCollection(lowerCaseName, ignoreNonExists); + if (errCode != E_OK) { + GLOGE("Drop collection failed. %d", errCode); + goto END; + } + + errCode = executor_->CleanCollectionOption(lowerCaseName); + if (errCode != E_OK && errCode != -E_NO_DATA) { + GLOGE("Clean collection option failed. %d", errCode); + } else { + errCode = E_OK; + } + +END: + if (errCode == E_OK) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return errCode; +} + +int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isIdExist) +{ + int errCode = E_OK; + filterAllPath = JsonCommon::ParsePath(filterObj, errCode); + if (errCode != E_OK) { + GLOGE("filter ParsePath failed"); + return errCode; + } + return CheckCommon::CheckFilter(filterObj, filterAllPath, isIdExist); +} + +int UpdateArgsCheck(const std::string &collection, const std::string &filter, const std::string &update, uint32_t flags) +{ + std::string lowerCaseCollName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + if (update.length() >= JSON_LENS_MAX || filter.length() >= JSON_LENS_MAX) { + GLOGE("args document's length is too long"); + return -E_OVER_LIMIT; + } + JsonObject updateObj = JsonObject::Parse(update, errCode, true); + if (errCode != E_OK) { + GLOGE("update Parsed failed"); + return errCode; + } + if (update != "{}") { + errCode = CheckCommon::CheckUpdata(updateObj); + if (errCode != E_OK) { + GLOGE("Updata format is illegal"); + return errCode; + } + } + if (flags != GRD_DOC_APPEND && flags != GRD_DOC_REPLACE) { + GLOGE("Check flags invalid."); + return -E_INVALID_ARGS; + } + return errCode; +} + +int GetUpDataRePlaceData(ResultSet &resultSet, const std::string &id, const std::string &update, std::string &valStr, + bool isReplace) +{ + std::string valueGotStr; + int errCode = resultSet.GetValue(valueGotStr); + if (errCode == -E_NO_DATA) { + GLOGW("Get original document not found."); + return -E_NOT_FOUND; + } else if (errCode != E_OK) { + GLOGE("Get original document failed. %d", errCode); + return errCode; + } + JsonObject updateValue = JsonObject::Parse(update, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse upsert value failed. %d", errCode); + return errCode; + } + JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, updateValue, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + +int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, + const std::string &update, bool &isReplace) +{ + std::lock_guard lock(dbMutex_); + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + int errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + std::string docId; + int count = 0; + std::string valStr; + auto coll = Collection(context->collectionName, executor_); + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; + } + // no start transaction inner + errCode = resultSet.GetNext(false, true); + if (errCode == -E_NO_DATA) { + // no need to set count + errCode = E_OK; + goto END; + } else if (errCode != E_OK) { + goto END; + } + resultSet.GetKey(docId); + errCode = GetUpDataRePlaceData(resultSet, docId, update, valStr, isReplace); + if (errCode != E_OK) { + goto END; + } + errCode = coll.UpdateDocument(docId, valStr); + if (errCode == E_OK) { + count++; + } else if (errCode == -E_NOT_FOUND) { + errCode = E_OK; + } +END: + if (errCode == E_OK) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return (errCode == E_OK) ? count : errCode; +} + +int DocumentStore::UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, + uint32_t flags) +{ + int errCode = UpdateArgsCheck(collection, filter, update, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + bool isIdExist = false; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isIdExist); + if (errCode != E_OK) { + return errCode; + } + bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); + std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; + context->collectionName = collection; + context->filter = filter; + context->ifShowId = true; + return UpdateDataIntoDB(context, filterObj, update, isReplace); +} + +int UpsertArgsCheck(const std::string &collection, const std::string &filter, const std::string &document, + uint32_t flags) +{ + std::string lowerCaseCollName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + if (document.length() >= JSON_LENS_MAX || filter.length() >= JSON_LENS_MAX) { + GLOGE("args length is too long"); + return -E_OVER_LIMIT; + } + if (flags != GRD_DOC_APPEND && flags != GRD_DOC_REPLACE) { + GLOGE("Check flags invalid."); + return -E_INVALID_ARGS; + } + return errCode; +} + +int CheckUpsertConflict(ResultSet &resultSet, JsonObject &filterObj, std::string &docId, Collection &coll, + bool &isDataExist) +{ + std::string val; // use to know whether there is data in the resultSet or not. + int errCode = resultSet.GetValue(val); + if (errCode == E_OK) { + isDataExist = true; + } + Value ValueDocument; + Key id(docId.begin(), docId.end()); + errCode = coll.GetDocumentById(id, ValueDocument); + if (errCode == E_OK && !(isDataExist)) { + GLOGE("id exist but filter does not match, data conflict"); + errCode = -E_DATA_CONFLICT; + } + return errCode; +} + +int GetUpsertRePlaceData(ResultSet &resultSet, JsonObject &documentObj, bool isReplace, std::string &valStr) +{ + int errCode = resultSet.GetValue(valStr); + if (errCode != E_OK || isReplace) { + valStr = documentObj.Print(); // If cant not find data, insert it. + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return E_OK; + } + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + GLOGW("Get original document failed. %d", errCode); + return errCode; + } else if (errCode == E_OK) { // document has been inserted + JsonObject originValue = JsonObject::Parse(valStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, documentObj, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + } + return errCode; +} + +int InsertIdToDocument(ResultSet &resultSet, JsonObject &filterObj, JsonObject &documentObj, std::string &docId) +{ + auto filterObjChild = filterObj.GetChild(); + bool isIdExist; + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); + int errCode = E_OK; + int ret = resultSet.GetNext(false, true); // All anomalies will be judged later + if (ret != E_OK && ret != -E_NO_DATA) { + return ret; + } + if (isIdExist) { + docId = idValue.GetStringValue(); + JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); // this errCode will always be E_OK. + documentObj.InsertItemObject(0, idObj); + } else { + if (ret == E_OK) { // E_OK means find data. + (void)resultSet.GetKey(docId); // This errCode will always be E_OK. + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + docId = docKey.key; + } + } + return errCode; +} + +int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, + const std::string &document, JsonObject &documentObj, bool &isReplace) +{ + std::lock_guard lock(dbMutex_); + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + int errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + Collection coll = Collection(context->collectionName, executor_); + int count = 0; + std::string docId; + ResultSet resultSet; + std::string newDocument; + bool isDataExist = false; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; + } + errCode = InsertIdToDocument(resultSet, filterObj, documentObj, docId); + if (errCode != E_OK) { + goto END; + } + errCode = CheckUpsertConflict(resultSet, filterObj, docId, coll, isDataExist); + // There are only three return values, the two other situation can continue to move forward. + if (errCode == -E_DATA_CONFLICT) { + GLOGE("upsert data conflict"); + goto END; + } + errCode = GetUpsertRePlaceData(resultSet, documentObj, isReplace, newDocument); + if (errCode != E_OK) { + goto END; + } + errCode = coll.UpsertDocument(docId, newDocument, isDataExist); + if (errCode == E_OK) { + count++; + } else if (errCode == -E_NOT_FOUND) { + errCode = E_OK; + } +END: + if (errCode == E_OK) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return (errCode == E_OK) ? count : errCode; +} + +int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentObj) +{ + int errCode = E_OK; + if (document != "{}") { + errCode = CheckCommon::CheckUpdata(documentObj); + if (errCode != E_OK) { + GLOGE("UpsertDocument document format is illegal"); + return errCode; + } + } + return errCode; +} + +int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, + const std::string &document, uint32_t flags) +{ + int errCode = UpsertArgsCheck(collection, filter, document, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + JsonObject documentObj = JsonObject::Parse(document, errCode, true); + if (errCode != E_OK) { + GLOGE("document Parsed failed"); + return errCode; + } + errCode = UpsertDocumentFormatCheck(document, documentObj); + if (errCode != E_OK) { + GLOGE("document format is illegal"); + return errCode; + } + bool isIdExist = false; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isIdExist); + if (errCode != E_OK) { + GLOGE("filter is invalid"); + return errCode; + } + std::shared_ptr context = std::make_shared(); + context->filter = filter; + context->collectionName = collection; + context->ifShowId = true; + context->isIdExist = isIdExist; + bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); + return UpsertDataIntoDB(context, filterObj, document, documentObj, isReplace); +} + +int InsertArgsCheck(const std::string &collection, const std::string &document, uint32_t flags) +{ + if (flags != 0u) { + GLOGE("InsertDocument flags is not zero"); + return -E_INVALID_ARGS; + } + std::string lowerCaseCollName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + if (document.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + +int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, + JsonObject &documentObj, bool &isIdExist) +{ + std::lock_guard lock(dbMutex_); + std::string id; + if (isIdExist) { + JsonObject documentObjChild = documentObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); + id = idValue.GetStringValue(); + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + id = docKey.key; + } + Collection coll = Collection(collection, executor_); + return coll.InsertDocument(id, document, isIdExist); +} + +int DocumentStore::InsertDocument(const std::string &collection, const std::string &document, uint32_t flags) +{ + int errCode = InsertArgsCheck(collection, document, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject documentObj = JsonObject::Parse(document, errCode, true); + if (errCode != E_OK) { + GLOGE("Document Parsed failed"); + return errCode; + } + bool isIdExist = true; + errCode = CheckCommon::CheckDocument(documentObj, isIdExist); + if (errCode != E_OK) { + return errCode; + } + return InsertDataIntoDB(collection, document, documentObj, isIdExist); +} + +int DeleteArgsCheck(const std::string &collection, const std::string &filter, uint32_t flags) +{ + if (flags != 0u) { + GLOGE("DeleteDocument flags is not zero"); + return -E_INVALID_ARGS; + } + std::string lowerCaseCollName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + if (filter.empty()) { + GLOGE("Filter is empty"); + return -E_INVALID_ARGS; + } + if (filter.length() >= JSON_LENS_MAX) { + GLOGE("filter's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + +int DocumentStore::DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj) +{ + std::lock_guard lock(dbMutex_); + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + Collection coll = Collection(context->collectionName, executor_); + int errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + std::string id; + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; + } + errCode = resultSet.GetNext(false, true); + if (errCode != E_OK) { + goto END; + } + resultSet.GetKey(id); +END: + if (errCode == E_OK) { + Key key(id.begin(), id.end()); + errCode = coll.DeleteDocument(key); + } + if (errCode == E_OK || errCode == E_NOT_FOUND) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return errCode; +} +int DocumentStore::DeleteDocument(const std::string &collection, const std::string &filter, uint32_t flags) +{ + int errCode = DeleteArgsCheck(collection, filter, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + return errCode; + } + bool isIdExist = false; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isIdExist); + if (errCode != E_OK) { + return errCode; + } + std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; + context->filter = filter; + context->collectionName = collection; + return DeleteDataFromDB(context, filterObj); +} +Collection DocumentStore::GetCollection(std::string &collectionName) +{ + return Collection(collectionName, executor_); +} + +int JudgeBoolViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + if (leafItem.GetBoolValue()) { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + if (index != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } + return E_OK; +} + +int JudgeStringViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + if (leafItem.GetStringValue() == "") { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + return -E_INVALID_ARGS; + } + return E_OK; +} + +int JudgeIntViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + if (leafItem.GetIntValue() == 0) { + if (index != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } else { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } + return E_OK; +} + +int JudgeViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + int errCode = E_OK; + switch (leafItem.GetValueType()) { + case ValueObject::ValueType::VALUE_BOOL: + errCode = JudgeBoolViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; + } + break; + case ValueObject::ValueType::VALUE_STRING: + errCode = JudgeStringViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; + } + break; + case ValueObject::ValueType::VALUE_NUMBER: + errCode = JudgeIntViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; + } + break; + default: + return -E_INVALID_ARGS; + } + return E_OK; +} + +int GetViewType(JsonObject &jsonObj, bool &viewType) +{ + std::vector leafValue = JsonCommon::GetLeafValue(jsonObj); + if (leafValue.size() == 0) { + return -E_INVALID_ARGS; + } + int ret = E_OK; + for (size_t i = 0; i < leafValue.size(); i++) { + ret = JudgeViewType(i, leafValue[i], viewType); + if (ret != E_OK) { + return ret; + } + } + return ret; +} + +int FindArgsCheck(const std::string &collection, const std::string &filter, const std::string &projection, + uint32_t flags) +{ + if (flags != 0u && flags != GRD_DOC_ID_DISPLAY) { + GLOGE("FindDocument flags is illegal"); + return -E_INVALID_ARGS; + } + std::string lowerCaseCollName; + int errCode = E_OK; + if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { + GLOGE("Check collection name invalid. %d", errCode); + return errCode; + } + if (filter.length() >= JSON_LENS_MAX || projection.length() >= JSON_LENS_MAX) { + GLOGE("args length is too long"); + return -E_OVER_LIMIT; + } + if (projection.length() >= JSON_LENS_MAX) { + GLOGE("projection's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + +int FindProjectionInit(const std::string &projection, const std::shared_ptr &context) +{ + int errCode = E_OK; + std::vector> allPath; + JsonObject projectionObj = JsonObject::Parse(projection, errCode, true); + if (errCode != E_OK) { + GLOGE("projection Parsed failed"); + return errCode; + } + bool viewType = false; + if (projection != "{}") { + allPath = JsonCommon::ParsePath(projectionObj, errCode); + if (errCode != E_OK) { + return errCode; + } + if (GetViewType(projectionObj, viewType) != E_OK) { + GLOGE("GetViewType failed"); + return -E_INVALID_ARGS; + } + errCode = CheckCommon::CheckProjection(projectionObj, allPath); + if (errCode != E_OK) { + GLOGE("projection format unvalid"); + return errCode; + } + } + context->projectionPath = std::move(allPath); + context->viewType = viewType; + return errCode; +} + +int DocumentStore::InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context) +{ + std::lock_guard lock(dbMutex_); + int errCode = E_OK; + Collection coll = Collection(context->collectionName, executor_); + if (IsExistResultSet(context->collectionName)) { + return -E_RESOURCE_BUSY; + } + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + errCode = executor_->StartTransaction(); + if (errCode != E_OK) { + return errCode; + } + bool isCollectionExist = coll.IsCollectionExists(errCode); + if (!isCollectionExist) { + errCode = -E_INVALID_ARGS; + } + if (errCode != E_OK) { + goto END; + } + errCode = InitResultSet(context, this, grdResultSet->resultSet_, true); + if (errCode == E_OK) { + collections_[context->collectionName] = nullptr; + } +END: + if (errCode == E_OK) { + executor_->Commit(); + } else { + executor_->Rollback(); + } + return errCode; +} + +int DocumentStore::FindDocument(const std::string &collection, const std::string &filter, + const std::string &projection, uint32_t flags, GRD_ResultSet *grdResultSet) +{ + int errCode = FindArgsCheck(collection, filter, projection, flags); + if (errCode != E_OK) { + GLOGE("delete arg is illegal"); + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + std::shared_ptr context = std::make_shared(); + errCode = FindProjectionInit(projection, context); + if (errCode != E_OK) { + return errCode; + } + bool isIdExist = false; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isIdExist); + if (errCode != E_OK) { + GLOGE("filter is invalid"); + return errCode; + } + if (flags == GRD_DOC_ID_DISPLAY) { + context->ifShowId = true; + } else { + context->ifShowId = false; + } + context->collectionName = collection; + context->filter = filter; + context->isIdExist = isIdExist; + return InitFindResultSet(grdResultSet, context); +} + +bool DocumentStore::IsExistResultSet(const std::string &collection) +{ + if (collections_.find(collection) != collections_.end()) { + GLOGE("DB is resource busy"); + return true; + } + return false; +} + +int DocumentStore::EraseCollection(const std::string &collectionName) +{ + std::lock_guard lock(dbMutex_); + if (collections_.find(collectionName) != collections_.end()) { + collections_.erase(collectionName); + return E_OK; + } + GLOGE("erase collection failed"); + return -E_INVALID_ARGS; +} + +void DocumentStore::OnClose(const std::function ¬ifier) +{ + closeNotifier_ = notifier; +} + +int DocumentStore::Close(uint32_t flags) +{ + std::lock_guard lock(dbMutex_); + if (flags == GRD_DB_CLOSE && !collections_.empty()) { + GLOGE("Close store failed with result set not closed."); + return -E_RESOURCE_BUSY; + } + + if (closeNotifier_) { + closeNotifier_(); + } + return E_OK; +} + +int DocumentStore::StartTransaction() +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->StartTransaction(); +} +int DocumentStore::Commit() +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->Commit(); +} +int DocumentStore::Rollback() +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->Rollback(); +} + +bool DocumentStore::IsCollectionExists(const std::string &collectionName, int &errCode) +{ + if (executor_ == nullptr) { + errCode = -E_INNER_ERROR; + return false; + } + return executor_->IsCollectionExists(collectionName, errCode); +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp similarity index 64% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp index 85a73cafb7c5ef43f86d281a24929f2f320ff3cf..138c86ab99caf2062b166fd4350508b56684b05e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store_manager.cpp @@ -13,8 +13,9 @@ * limitations under the License. */ -#include "db_config.h" #include "document_store_manager.h" + +#include "db_config.h" #include "doc_errno.h" #include "grd_base/grd_type_export.h" #include "kv_store_manager.h" @@ -35,22 +36,25 @@ bool CheckDBCloseFlag(unsigned int flag) return (flag == GRD_DB_CLOSE) || (flag == GRD_DB_CLOSE_IGNORE_ERROR); } -bool CheckDBCreate(unsigned int flags, const std::string &path) +bool CheckDBCreate(uint32_t flags, const std::string &path) { if ((flags & GRD_DB_OPEN_CREATE) == 0 && !OSAPI::CheckPathExistence(path)) { return false; } return true; } -} +} // namespace -int DocumentStoreManager::GetDocumentStore(const std::string &path, const std::string &config, unsigned int flags, +std::mutex DocumentStoreManager::openCloseMutex_; +std::map DocumentStoreManager::dbConnCount_; + +int DocumentStoreManager::GetDocumentStore(const std::string &path, const std::string &config, uint32_t flags, DocumentStore *&store) { std::string canonicalPath; std::string dbName; - int errCode = E_OK; - if (!CheckDBPath(path, canonicalPath, dbName, errCode)) { + int errCode = CheckDBPath(path, canonicalPath, dbName); + if (errCode != E_OK) { GLOGE("Check document db file path failed."); return errCode; } @@ -65,14 +69,19 @@ int DocumentStoreManager::GetDocumentStore(const std::string &path, const std::s GLOGE("Check document db open flags failed."); return -E_INVALID_ARGS; } - if (!CheckDBCreate(flags, path)) { GLOGE("Open db failed, file no exists."); return -E_INVALID_ARGS; } + std::lock_guard lock(openCloseMutex_); + + std::string dbRealPath = canonicalPath + "/" + dbName; + auto it = dbConnCount_.find(dbRealPath); + bool isFirstOpen = (it == dbConnCount_.end() || it->second == 0); + KvStoreExecutor *executor = nullptr; - errCode = KvStoreManager::GetKvStore(canonicalPath + "/" + dbName, dbConfig, executor); + errCode = KvStoreManager::GetKvStore(dbRealPath, dbConfig, isFirstOpen, executor); if (errCode != E_OK) { GLOGE("Open document store failed. %d", errCode); return errCode; @@ -80,59 +89,67 @@ int DocumentStoreManager::GetDocumentStore(const std::string &path, const std::s store = new (std::nothrow) DocumentStore(executor); if (store == nullptr) { - return -E_OUT_OF_MEMORY; + delete executor; + GLOGE("Memory allocation failed!"); + return -E_FAILED_MEMORY_ALLOCATE; } + store->OnClose([dbRealPath]() { + dbConnCount_[dbRealPath]--; + }); + + if (isFirstOpen) { + dbConnCount_[dbRealPath] = 1; + } else { + dbConnCount_[dbRealPath]++; + } return errCode; } -int DocumentStoreManager::CloseDocumentStore(DocumentStore *store, unsigned int flags) +int DocumentStoreManager::CloseDocumentStore(DocumentStore *store, uint32_t flags) { if (!CheckDBCloseFlag(flags)) { GLOGE("Check document db close flags failed."); return -E_INVALID_ARGS; } + std::lock_guard lock(openCloseMutex_); + int errCode = store->Close(flags); + if (errCode != E_OK) { + GLOGE("Close document store failed. %d", errCode); + return errCode; + } + delete store; return E_OK; } -bool DocumentStoreManager::CheckDBPath(const std::string &path, std::string &canonicalPath, std::string &dbName, - int &errCode) +int DocumentStoreManager::CheckDBPath(const std::string &path, std::string &canonicalPath, std::string &dbName) { if (path.empty()) { GLOGE("Invalid path empty"); - errCode = -E_INVALID_ARGS; - return false; + return -E_INVALID_ARGS; } if (path.back() == '/') { GLOGE("Invalid path end with slash"); - errCode = -E_INVALID_ARGS; - return false; + return -E_INVALID_ARGS; } std::string dirPath; OSAPI::SplitFilePath(path, dirPath, dbName); - int innerErrCode = OSAPI::GetRealPath(dirPath, canonicalPath); - if (innerErrCode != E_OK) { + int errCode = OSAPI::GetRealPath(dirPath, canonicalPath); + if (errCode != E_OK) { GLOGE("Get real path failed. %d", errCode); - errCode = -E_FILE_OPERATION; - return false; + return -E_FILE_OPERATION; } if (!OSAPI::CheckPermission(canonicalPath)) { - GLOGE("Check path permission failed. %d", errCode); - errCode = -E_FILE_OPERATION; - return false; + GLOGE("Check path permission failed."); + return -E_FILE_OPERATION; } - return true; -} - -bool DocumentStoreManager::CheckDBConfig(const std::string &config, int &errCode) -{ - return true; + return E_OK; } -} // DocumentDB \ No newline at end of file +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ab699c391b76942f6a9512b545c408308f9ebd3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp @@ -0,0 +1,83 @@ +/* +* 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 "projection_tree.h" + +namespace DocumentDB { +constexpr int JSON_DEEP_MAX = 4; + +int ProjectionTree::ParseTree(std::vector> &path) +{ + ProjectionNode *node = &node_; + if (node == nullptr) { + return E_OK; + } + 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]]; + } + } + } + return E_OK; +} + +bool ProjectionTree::SearchTree(std::vector &singlePath, size_t &index) +{ + ProjectionNode *node = &node_; + for (size_t i = 0; i < singlePath.size(); i++) { + if (node->sonNode[singlePath[i]] != nullptr) { + node = node->sonNode[singlePath[i]]; + if (node->isDeepest) { + index = i + 1; + } + } else { + return false; + } + } + return true; +} + +int ProjectionNode::DeleteProjectionNode() +{ + for (auto item : sonNode) { + if (item.second != nullptr) { + delete item.second; + item.second = nullptr; + } + } + return E_OK; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd28c02696ac13e20c6ee42e6a5bd0fddbde028c --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp @@ -0,0 +1,292 @@ +/* +* 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 "result_set.h" + +#include + +#include "db_constant.h" +#include "document_key.h" +#include "log_print.h" +#include "securec.h" + +namespace DocumentDB { +constexpr const char *KEY_ID = "_id"; + +ResultSet::ResultSet() {} +ResultSet::~ResultSet() +{ + context_ = nullptr; +} +int ResultSet::EraseCollection() +{ + if (store_ != nullptr) { + store_->EraseCollection(context_->collectionName); + } + return E_OK; +} +int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch) +{ + isCutBranch_ = isCutBranch; + context_ = context; + store_ = store; + return E_OK; +} + +int ResultSet::GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData) +{ + std::pair value; + Collection coll = store_->GetCollection(context_->collectionName); + filterObj.DeleteItemFromObject(KEY_ID); + int errCode = coll.GetMatchedDocument(filterObj, key, value, context_->isIdExist); + if (errCode == -E_NOT_FOUND) { + return -E_NO_DATA; + } + jsonData.assign(value.second.begin(), value.second.end()); + jsonKey.assign(value.first.begin(), value.first.end()); + lastKeyIndex_ = jsonKey; + if (isCutBranch_) { + errCode = CutJsonBranch(jsonKey, jsonData); + if (errCode != E_OK) { + GLOGE("cut branch faild"); + } + } + return errCode; +} + +int ResultSet::GetNextWithField() +{ + int errCode = E_OK; + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + Key key; + if (context_->isIdExist) { + if (index_ == 0) { // get id from filter, if alreay has got id once, get from lastKeyIndex. + JsonObject filterObjChild = filterObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); + std::string idKey = idValue.GetStringValue(); + key.assign(idKey.begin(), idKey.end()); + } else { // Use id to find data that can only get one data. + matchData_.first.clear(); // Delete previous data. + matchData_.second.clear(); + return -E_NO_DATA; + } + } else { + key.assign(lastKeyIndex_.begin(), lastKeyIndex_.end()); + } + matchData_.first.clear(); + matchData_.second.clear(); + std::string jsonKey; + std::string jsonData; + errCode = GetValueFromDB(key, filterObj, jsonKey, jsonData); + matchData_ = std::make_pair(jsonKey, jsonData); + return errCode; +} + +int ResultSet::GetNextInner(bool isNeedCheckTable) +{ + int errCode = E_OK; + if (isNeedCheckTable) { + std::string lowerCaseName = context_->collectionName; + std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { + return std::tolower(c); + }); + bool isCollectionExist = store_->IsCollectionExists(DBConstant::COLL_PREFIX + lowerCaseName, errCode); + if (errCode != E_OK) { + return errCode; + } + if (!isCollectionExist) { + return -E_INVALID_ARGS; + } + } + errCode = GetNextWithField(); + index_++; + if (errCode != E_OK) { + return errCode; + } + if (matchData_.second.empty()) { + return -E_NO_DATA; + } + return E_OK; +} + +int ResultSet::GetNext(bool isNeedTransaction, bool isNeedCheckTable) +{ + if (!isNeedTransaction) { + return GetNextInner(isNeedCheckTable); + } + std::lock_guard lock(store_->dbMutex_); + int errCode = store_->StartTransaction(); + if (errCode != E_OK) { + GLOGE("Start transaction faild"); + return errCode; + } + errCode = GetNextInner(isNeedCheckTable); + if (errCode == E_OK || errCode == -E_NO_DATA) { + store_->Commit(); + } else { + store_->Rollback(); + } + return errCode; +} + +int ResultSet::GetValue(char **value) +{ + std::lock_guard lock(store_->dbMutex_); + if (matchData_.first.empty()) { + GLOGE("The value vector in resultSet is empty"); + return -E_NO_DATA; + } + std::string jsonData = matchData_.second; + char *jsonstr = new char[jsonData.size() + 1]; + if (jsonstr == nullptr) { + GLOGE("Memory allocation failed!"); + return -E_FAILED_MEMORY_ALLOCATE; + } + int err = strcpy_s(jsonstr, jsonData.size() + 1, jsonData.c_str()); + if (err != 0) { + GLOGE("strcpy_s failed"); + delete[] jsonstr; + return -E_NO_DATA; + } + *value = jsonstr; + return E_OK; +} + +int ResultSet::GetValue(std::string &value) +{ + if (matchData_.first.empty()) { + GLOGE("The value vector in resultSet is empty"); + return -E_NO_DATA; + } + value = matchData_.second; + return E_OK; +} + +int ResultSet::GetKey(std::string &key) +{ + key = matchData_.first; + if (key.empty()) { + GLOGE("can not get data, because it is empty"); + return -E_NO_DATA; + } + return E_OK; +} + +int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePath, + std::vector> &allCutPath) +{ + if (node == nullptr) { + GLOGE("No node to cut"); + return -E_NO_DATA; + } + JsonObject nodeInstance = *node; + while (!nodeInstance.IsNull()) { + singlePath.emplace_back(nodeInstance.GetItemField()); + size_t index = 0; + bool isMatch = context_->projectionTree.SearchTree(singlePath, index); + if ((nodeInstance.GetType() == JsonObject::Type::JSON_ARRAY && isMatch && index == 0) || + (!isMatch && index == 0)) { + allCutPath.emplace_back(singlePath); + } + if (nodeInstance.GetType() != JsonObject::Type::JSON_ARRAY && !nodeInstance.GetChild().IsNull()) { + JsonObject nodeChiled = nodeInstance.GetChild(); + CheckCutNode(&nodeChiled, singlePath, allCutPath); + } + singlePath.pop_back(); + nodeInstance = nodeInstance.GetNext(); + } + return E_OK; +} + +JsonObject CreatIdObj(const std::string &idStr, int errCode) +{ + std::stringstream sstream; + sstream << "{\"_id\":" + << "\"" << idStr << "\"}"; + JsonObject idObj = JsonObject::Parse(sstream.str(), errCode, true); // cant be faild. + return idObj; +} + +int InsertId(JsonObject &cjsonObj, std::string &jsonKey) +{ + if (jsonKey.empty()) { + GLOGE("Genalral Id faild"); + return -E_INNER_ERROR; + } + int errCode = E_OK; + JsonObject idObj = CreatIdObj(jsonKey, errCode); + if (errCode != E_OK) { + GLOGE("CreatIdObj faild"); + return errCode; + } + cjsonObj.InsertItemObject(0, idObj.GetChild()); // idObj's child is _id node + return E_OK; +} + +int ResultSet::CutJsonBranch(std::string &jsonKey, std::string &jsonData) +{ + int errCode; + JsonObject cjsonObj = JsonObject::Parse(jsonData, errCode, true); + if (errCode != E_OK) { + GLOGE("jsonData Parsed failed"); + return errCode; + } + bool isIdExistInValue = true; // if id exsit in the value string that get from db. + bool isInsertIdflag = false; + isIdExistInValue = cjsonObj.GetObjectItem("_id", errCode).IsNull() ? false : true; + if (context_->ifShowId && !isIdExistInValue) { + isInsertIdflag = true; // ifShowId is true,and then the data taken out does not have IDs, insert id. + } + if (context_->viewType) { + std::vector singlePath; + JsonObject cjsonObjChild = cjsonObj.GetChild(); + std::vector> allCutPath; + errCode = CheckCutNode(&cjsonObjChild, singlePath, allCutPath); + if (errCode != E_OK) { + GLOGE("The node in CheckCutNode is nullptr"); + return errCode; + } + for (const auto &singleCutPath : allCutPath) { + if (!context_->ifShowId || singleCutPath[0] != KEY_ID) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPath); + } + if (singleCutPath[0] == KEY_ID && !isIdExistInValue) { // projection has Id, and its showType is true. + isInsertIdflag = true; + } + } + } + if (isInsertIdflag) { + errCode = InsertId(cjsonObj, jsonKey); + if (errCode != E_OK) { + return errCode; + } + } + if (!context_->viewType) { + for (const auto &singleCutPaht : context_->projectionPath) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); + } + if (!context_->ifShowId) { + std::vector idPath; + idPath.emplace_back(KEY_ID); + cjsonObj.DeleteItemDeeplyOnTarget(idPath); + } + } + jsonData = cjsonObj.Print(); + return E_OK; +} +} // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd9acaeb265af70df00b0f7374f3d6df381c0c8f --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp @@ -0,0 +1,39 @@ +/* +* 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 "result_set_common.h" +#include "grd_format_config.h" +#include "doc_errno.h" +#include "grd_base/grd_error.h" + +namespace DocumentDB { +class ValueObject; +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch) +{ + if (isCutBranch) { + for (const auto &singlePath : context->projectionPath) { + if (singlePath[0] == KEY_ID && context->viewType == true) { // projection has Id and viewType is true + context->ifShowId = true; + break; + } + } + if (context->projectionTree.ParseTree(context->projectionPath) == -E_INVALID_ARGS) { + GLOGE("Parse ProjectionTree failed"); + return -E_INVALID_ARGS; + } + } + return resultSet.Init(context, store, isCutBranch); +} +} // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h similarity index 65% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h index b2e83a930943673fa6915ade08ec839de22233be..bd1cba711e6efd0cd2fb5bd291fe07ff74305f0e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h @@ -17,9 +17,10 @@ #define JSON_OBJECT_H #include +#include #include -#include #include +#include #include "cJSON.h" @@ -32,12 +33,10 @@ public: VALUE_NUMBER, VALUE_STRING, }; - ValueObject() = default; explicit ValueObject(bool val); explicit ValueObject(double val); explicit ValueObject(const char *val); - explicit ValueObject(const std::string &val); ValueType GetValueType() const; bool GetBoolValue() const; @@ -53,41 +52,47 @@ private: }; std::string stringValue; }; +using JsonFieldPath = std::vector; using ResultValue = ValueObject; using JsonFieldPath = std::vector; class JsonObject { public: - static JsonObject Parse(const std::string &jsonStr, int &errCode, bool caseSensitive = false); - - ~JsonObject (); + static JsonObject Parse(const std::string &jsonStr, int &errCode, bool caseSensitive = false, + bool isFilter = false); + bool operator==(const JsonObject &other) const; // If the two nodes exist with a different fieldName, then return 0. + ~JsonObject(); std::string Print() const; JsonObject GetObjectItem(const std::string &field, int &errCode); - JsonObject GetArrayItem(int index, int &errCode); JsonObject GetNext() const; JsonObject GetChild() const; int DeleteItemFromObject(const std::string &field); - int AddItemToObject(const JsonObject &item); int AddItemToObject(const std::string &fieldName, const JsonObject &item); + int AddItemToObject(const std::string &fieldName); ValueObject GetItemValue() const; - void SetItemValue(const ValueObject &value) const; + void ReplaceItemInArray(const int &index, const JsonObject &newItem, int &errCode); + void ReplaceItemInObject(const std::string &fieldName, const JsonObject &newItem, int &errCode); + int InsertItemObject(int which, const JsonObject &newItem); - std::string GetItemFiled() const; + std::string GetItemField() const; + std::string GetItemField(int &errCode) const; bool IsFieldExists(const JsonFieldPath &jsonPath) const; + bool IsFieldExistsPowerMode(const JsonFieldPath &jsonPath) const; JsonObject FindItem(const JsonFieldPath &jsonPath, int &errCode) const; + JsonObject FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const; ValueObject GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const; - int DeleteItemOnTarget(const JsonFieldPath &path); + int DeleteItemDeeplyOnTarget(const JsonFieldPath &path); bool IsNull() const; - + int GetDeep(); enum class Type { - JSON_LEAF, + JSON_LEAF, // Corresponds to nodes of type null, number, string, true false in CJSON JSON_OBJECT, JSON_ARRAY }; @@ -95,15 +100,15 @@ public: private: JsonObject(); - int Init(const std::string &str); - + int Init(const std::string &str, bool isFilter = false); + int CheckJsonRepeatField(cJSON *object, bool isFirstFloor); + int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor); int GetDeep(cJSON *cjson); - - + int CheckNumber(cJSON *cJSON); cJSON *cjson_ = nullptr; + int jsonDeep_ = 0; bool isOwner_ = false; bool caseSensitive_ = false; }; -} // DocumentDB +} // namespace DocumentDB #endif // JSON_OBJECT_H - diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h similarity index 54% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h index 8037fc6bcbf2644e43dccb298e7c774ec9cd1a0b..a12bda14fae0de0c52464b2369d96db5ca4c892f 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h @@ -17,24 +17,32 @@ #define KV_STORE_EXECUTOR_H #include -#include "doc_common.h" + +#include "check_common.h" namespace DocumentDB { class KvStoreExecutor { public: virtual ~KvStoreExecutor() = default; - virtual int PutData(const std::string &collName, const Key &key, const Value &value) = 0; - virtual int GetData(const std::string &collName, const Key &key, Value &value) const = 0; - virtual int DelData(const std::string &collName, const Key &key) = 0; + virtual int StartTransaction() = 0; + virtual int Commit() = 0; + virtual int Rollback() = 0; + + virtual int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int GetDataByKey(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataById(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const = 0; + virtual int DelData(const std::string &collName, Key &key) = 0; - virtual int CreateCollection(const std::string &name, bool ignoreExists) = 0; + virtual int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) = 0; virtual int DropCollection(const std::string &name, bool ignoreNonExists) = 0; virtual bool IsCollectionExists(const std::string &name, int &errCode) = 0; - virtual int GetCollectionOption(const std::string &name, std::string &option) = 0; virtual int SetCollectionOption(const std::string &name, const std::string &option) = 0; virtual int CleanCollectionOption(const std::string &name) = 0; }; -} // DocumentDB +} // namespace DocumentDB #endif // KV_STORE_EXECUTOR_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_manager.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h similarity index 88% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_manager.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h index 97b79f649350a92b31bdc5b4e115e4a02d2f398c..5589c20aa180f28794906eb74b7d7df82b516cf5 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_manager.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_manager.h @@ -17,14 +17,15 @@ #define KV_STORE_MANAGER_H #include +#include "check_common.h" #include "db_config.h" -#include "doc_common.h" #include "kv_store_executor.h" namespace DocumentDB { class KvStoreManager { public: - static int GetKvStore(const std::string &path, const DBConfig &config, KvStoreExecutor *&executor); + static int GetKvStore(const std::string &path, const DBConfig &config, bool isFirstOpen, + KvStoreExecutor *&executor); }; -} // DocumentDB +} // namespace DocumentDB #endif // KV_STORE_MANAGER_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp similarity index 50% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp index 661dfeeb336a927c683b439e0066ce50f1b0d245..26c50fd8667a29c81e251c6fb0a3776099ea85c1 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp @@ -14,25 +14,23 @@ */ #include "json_object.h" + #include +#include +#include + #include "doc_errno.h" #include "log_print.h" -// #include "grd_format_config.h" namespace DocumentDB { - namespace { -#define COLLECTION_LENS_MAX (512) -#define JSON_LENS_MAX (512) -#define JSON_DEEP_MAX (4) - bool IsNumber(const std::string &str) { return std::all_of(str.begin(), str.end(), [](char c) { return std::isdigit(c); }); } -} +} // namespace ValueObject::ValueObject(bool val) { @@ -52,12 +50,6 @@ ValueObject::ValueObject(const char *val) stringValue = val; } -ValueObject::ValueObject(const std::string &val) -{ - valueType = ValueType::VALUE_STRING; - stringValue = val; -} - ValueObject::ValueType ValueObject::GetValueType() const { return valueType; @@ -70,7 +62,7 @@ bool ValueObject::GetBoolValue() const int64_t ValueObject::GetIntValue() const { - return static_cast(doubleValue + 0.5); + return static_cast(std::llround(doubleValue)); } double ValueObject::GetDoubleValue() const @@ -83,31 +75,34 @@ std::string ValueObject::GetStringValue() const return stringValue; } -JsonObject JsonObject::Parse(const std::string &jsonStr, int &errCode, bool caseSensitive) +JsonObject JsonObject::Parse(const std::string &jsonStr, int &errCode, bool caseSensitive, bool isFilter) { JsonObject obj; - errCode = obj.Init(jsonStr); + errCode = obj.Init(jsonStr, isFilter); obj.caseSensitive_ = caseSensitive; return obj; } JsonObject::JsonObject() { + cjson_ = nullptr; } JsonObject::~JsonObject() { - if (isOwner_ == true) { + if (isOwner_) { cJSON_Delete(cjson_); } } +bool JsonObject::operator==(const JsonObject &other) const +{ + return (cJSON_Compare(this->cjson_, other.cjson_, true) != 0); // CaseSensitive +} + bool JsonObject::IsNull() const { - if (cjson_ == nullptr) { - return true; - } - return false; + return (cjson_ == nullptr); } JsonObject::Type JsonObject::GetType() const @@ -120,10 +115,24 @@ JsonObject::Type JsonObject::GetType() const return JsonObject::Type::JSON_LEAF; } +int JsonObject::GetDeep() +{ + if (cjson_ == nullptr) { + GLOGE("cJson is nullptr,deep is 0"); + return 0; + } + if (jsonDeep_ != 0) { + return jsonDeep_; + } + jsonDeep_ = GetDeep(cjson_); + return jsonDeep_; +} + int JsonObject::GetDeep(cJSON *cjson) { if (cjson->child == nullptr) { - return 1; // leaf node + jsonDeep_ = 0; + return 0; // leaf node } int depth = -1; @@ -132,45 +141,144 @@ int JsonObject::GetDeep(cJSON *cjson) depth = std::max(depth, GetDeep(child) + 1); child = child->next; } + jsonDeep_ = depth; return depth; } -int JsonObject::Init(const std::string &str) +int JsonObject::CheckNumber(cJSON *item) { - if (str.length() + 1 > JSON_LENS_MAX) { - return -E_INVALID_ARGS; + std::queue cjsonQueue; + cjsonQueue.push(item); + while (!cjsonQueue.empty()) { + cJSON *node = cjsonQueue.front(); + cjsonQueue.pop(); + if (node == nullptr) { + return -E_INVALID_ARGS; + } + if (cJSON_IsNumber(node)) { // node is not null all the time + double value = cJSON_GetNumberValue(node); + if (value > __DBL_MAX__ || value < -__DBL_MAX__) { + return -E_INVALID_ARGS; + } + } + if (node->child != nullptr) { + cjsonQueue.push(node->child); + } + if (node->next != nullptr) { + cjsonQueue.push(node->next); + } } + return E_OK; +} + +int JsonObject::Init(const std::string &str, bool isFilter) +{ const char *end = NULL; isOwner_ = true; cjson_ = cJSON_ParseWithOpts(str.c_str(), &end, true); if (cjson_ == nullptr) { + GLOGE("Json's format is wrong"); return -E_INVALID_JSON_FORMAT; } if (cjson_->type != cJSON_Object) { + GLOGE("after Parse,cjson_'s type is not cJSON_Object"); return -E_INVALID_ARGS; } - if (GetDeep(cjson_) > JSON_DEEP_MAX) { + int ret = CheckNumber(cjson_); + if (ret == -E_INVALID_ARGS) { + GLOGE("Int value is larger than double"); return -E_INVALID_ARGS; } + if (!isFilter) { + bool isFirstFloor = true; + ret = CheckJsonRepeatField(cjson_, isFirstFloor); + if (ret != E_OK) { + return ret; + } + } return E_OK; } +int JsonObject::CheckJsonRepeatField(cJSON *object, bool isFirstFloor) +{ + if (object == nullptr) { + return -E_INVALID_ARGS; + } + int ret = E_OK; + int type = object->type; + if (type != cJSON_Object && type != cJSON_Array) { + return ret; + } + std::set fieldSet; + cJSON *subObj = object->child; + while (subObj != nullptr) { + ret = CheckSubObj(fieldSet, subObj, type, isFirstFloor); + if (ret != E_OK) { + break; + } + subObj = subObj->next; + } + return ret; +} + +bool IsFieldNameLegal(const std::string &fieldName) +{ + for (auto oneChar : fieldName) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return false; + } + } + return true; +} + +int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor) +{ + if (subObj == nullptr) { + return -E_INVALID_ARGS; + } + std::string fieldName; + if (subObj->string != nullptr) { + fieldName = subObj->string; + if (!isFirstFloor) { + if (!IsFieldNameLegal(fieldName)) { + return -E_INVALID_ARGS; + } + } + if (!fieldName.empty() && isdigit(fieldName[0])) { + return -E_INVALID_ARGS; + } + } + isFirstFloor = false; + if (parentType == cJSON_Array) { + return CheckJsonRepeatField(subObj, isFirstFloor); + } + if (fieldName.empty()) { + return -E_INVALID_JSON_FORMAT; + } + if (fieldSet.find(fieldName) == fieldSet.end()) { + fieldSet.insert(fieldName); + } else { + return -E_INVALID_JSON_FORMAT; + } + return CheckJsonRepeatField(subObj, isFirstFloor); +} + std::string JsonObject::Print() const { if (cjson_ == nullptr) { return ""; } char *ret = cJSON_PrintUnformatted(cjson_); - std::string str = ret; + std::string str = (ret == nullptr ? "" : ret); cJSON_free(ret); return str; } JsonObject JsonObject::GetObjectItem(const std::string &field, int &errCode) { - if (cjson_ == nullptr || (cjson_->type & cJSON_Object) != cJSON_Object) { + if (cjson_ == nullptr || cjson_->type != cJSON_Object) { errCode = -E_INVALID_ARGS; return JsonObject(); } @@ -188,22 +296,6 @@ JsonObject JsonObject::GetObjectItem(const std::string &field, int &errCode) return item; } -JsonObject JsonObject::GetArrayItem(int index, int &errCode) -{ - if (cjson_ == nullptr || (cjson_->type & cJSON_Array) != cJSON_Array) { - errCode = -E_INVALID_ARGS; - return JsonObject(); - } - - JsonObject item; - item.caseSensitive_ = caseSensitive_; - item.cjson_ = cJSON_GetArrayItem(cjson_, index); - if (item.cjson_ == nullptr) { - errCode = -E_NOT_FOUND; - } - return item; -} - JsonObject JsonObject::GetNext() const { if (cjson_ == nullptr) { @@ -234,32 +326,46 @@ JsonObject JsonObject::GetChild() const int JsonObject::DeleteItemFromObject(const std::string &field) { - if (field == "") { + if (field.empty()) { return E_OK; } cJSON_DeleteItemFromObjectCaseSensitive(cjson_, field.c_str()); return E_OK; } -int JsonObject::AddItemToObject(const JsonObject &item) +int JsonObject::AddItemToObject(const std::string &fieldName, const JsonObject &item) { + if (cjson_ == nullptr) { + return -E_ERROR; + } + if (item.IsNull()) { GLOGD("Add null object."); return E_OK; } - + if (cjson_->type == cJSON_Array) { + int n = 0; + cJSON *child = cjson_->child; + while (child != nullptr) { + child = child->next; + n++; + } + if (IsNumber(fieldName) && n <= std::stoi(fieldName)) { + GLOGE("Add item object to array over size."); + return -E_NO_DATA; + } + } + if (cjson_->type != cJSON_Object) { + GLOGE("type conflict."); + return -E_DATA_CONFLICT; + } cJSON *cpoyItem = cJSON_Duplicate(item.cjson_, true); - cJSON_AddItemToObject(cjson_, item.GetItemFiled().c_str(), cpoyItem); + cJSON_AddItemToObject(cjson_, fieldName.c_str(), cpoyItem); return E_OK; } -int JsonObject::AddItemToObject(const std::string &fieldName, const JsonObject &item) +int JsonObject::AddItemToObject(const std::string &fieldName) { - if (item.IsNull()) { - GLOGD("Add null object."); - return E_OK; - } - // TODO: check item exist if (cjson_->type == cJSON_Array) { int n = 0; cJSON *child = cjson_->child; @@ -269,11 +375,15 @@ int JsonObject::AddItemToObject(const std::string &fieldName, const JsonObject & } if (IsNumber(fieldName) && n <= std::stoi(fieldName)) { GLOGE("Add item object to array over size."); - return -E_DATA_CONFLICT; + return -E_NO_DATA; } } - cJSON *cpoyItem = cJSON_Duplicate(item.cjson_, true); - cJSON_AddItemToObject(cjson_, fieldName.c_str(), cpoyItem); + if (cjson_->type != cJSON_Object) { + GLOGE("type conflict."); + return -E_DATA_CONFLICT; + } + cJSON *emptyitem = cJSON_CreateObject(); + cJSON_AddItemToObject(cjson_, fieldName.c_str(), emptyitem); return E_OK; } @@ -282,7 +392,6 @@ ValueObject JsonObject::GetItemValue() const if (cjson_ == nullptr) { return ValueObject(); } - ValueObject value; switch (cjson_->type) { case cJSON_False: @@ -304,24 +413,46 @@ ValueObject JsonObject::GetItemValue() const return value; } -void JsonObject::SetItemValue(const ValueObject &value) const +void JsonObject::ReplaceItemInObject(const std::string &fieldName, const JsonObject &newItem, int &errCode) +{ + if (!newItem.IsNull() || !this->IsNull()) { + if (this->GetType() == JsonObject::Type::JSON_OBJECT) { + if (!(this->GetObjectItem(fieldName.c_str(), errCode).IsNull())) { + cJSON *copyItem = cJSON_Duplicate(newItem.cjson_, true); + cJSON_ReplaceItemInObjectCaseSensitive(this->cjson_, fieldName.c_str(), copyItem); + } else { + cJSON *copyItem = cJSON_Duplicate(newItem.cjson_, true); + cJSON_AddItemToObject(this->cjson_, fieldName.c_str(), copyItem); + } + } + } +} + +void JsonObject::ReplaceItemInArray(const int &index, const JsonObject &newItem, int &errCode) +{ + if (!newItem.IsNull() || !this->IsNull()) { + if (this->GetType() == JsonObject::Type::JSON_ARRAY) { + cJSON *copyItem = cJSON_Duplicate(newItem.cjson_, true); + cJSON_ReplaceItemInArray(this->cjson_, index, copyItem); + } + } +} + +int JsonObject::InsertItemObject(int which, const JsonObject &newItem) { if (cjson_ == nullptr) { - return; + return E_OK; } - switch(value.GetValueType()) { - case ValueObject::ValueType::VALUE_NUMBER: - cJSON_SetNumberValue(cjson_, value.GetDoubleValue()); - break; - case ValueObject::ValueType::VALUE_STRING: - cJSON_SetValuestring(cjson_, value.GetStringValue().c_str()); - break; - default: - break; + if (newItem.IsNull()) { + GLOGD("Add null object."); + return E_OK; } + cJSON *cpoyItem = cJSON_Duplicate(newItem.cjson_, true); + cJSON_InsertItemInArray(cjson_, which, cpoyItem); + return E_OK; } -std::string JsonObject::GetItemFiled() const +std::string JsonObject::GetItemField() const { if (cjson_ == nullptr) { return ""; @@ -329,7 +460,7 @@ std::string JsonObject::GetItemFiled() const if (cjson_->string == nullptr) { cJSON *tail = cjson_; - while(tail->next != nullptr) { + while (tail->next != nullptr) { tail = tail->next; } @@ -345,6 +476,16 @@ std::string JsonObject::GetItemFiled() const } } +std::string JsonObject::GetItemField(int &errCode) const +{ + if (cjson_ == nullptr || cjson_->string == nullptr) { + errCode = E_INVALID_ARGS; + return ""; + } + errCode = E_OK; + return cjson_->string; +} + cJSON *GetChild(cJSON *cjson, const std::string &field, bool caseSens) { if (cjson->type == cJSON_Object) { @@ -365,6 +506,34 @@ cJSON *GetChild(cJSON *cjson, const std::string &field, bool caseSens) return nullptr; } +cJSON *GetChildPowerMode(cJSON *cjson, const std::string &field, bool caseSens) +{ + if (cjson->type != cJSON_Object && cjson->type != cJSON_Array) { + GLOGW("Invalid json field type, expect object or array."); + return nullptr; + } else if (cjson->type == cJSON_Object) { + if (caseSens) { + return cJSON_GetObjectItemCaseSensitive(cjson, field.c_str()); + } else { + return cJSON_GetObjectItem(cjson, field.c_str()); + } + } + + // type is cJSON_Array + if (!IsNumber(field)) { + cjson = cjson->child; + while (cjson != nullptr) { + cJSON *resultItem = GetChild(cjson, field, caseSens); + if (resultItem != nullptr) { + return resultItem; + } + cjson = cjson->next; + } + return nullptr; + } + return cJSON_GetArrayItem(cjson, std::stoi(field)); +} + cJSON *MoveToPath(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) { for (const auto &field : jsonPath) { @@ -376,11 +545,27 @@ cJSON *MoveToPath(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) return cjson; } +cJSON *MoveToPathPowerMode(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) +{ + for (const auto &field : jsonPath) { + cjson = GetChildPowerMode(cjson, field, caseSens); + if (cjson == nullptr) { + break; + } + } + return cjson; +} + bool JsonObject::IsFieldExists(const JsonFieldPath &jsonPath) const { return (MoveToPath(cjson_, jsonPath, caseSensitive_) != nullptr); } +bool JsonObject::IsFieldExistsPowerMode(const JsonFieldPath &jsonPath) const +{ + return (MoveToPathPowerMode(cjson_, jsonPath, caseSensitive_) != nullptr); +} + JsonObject JsonObject::FindItem(const JsonFieldPath &jsonPath, int &errCode) const { if (jsonPath.empty()) { @@ -388,7 +573,6 @@ JsonObject JsonObject::FindItem(const JsonFieldPath &jsonPath, int &errCode) con curr.cjson_ = cjson_; curr.caseSensitive_ = caseSensitive_; curr.isOwner_ = false; - GLOGW("Path empty, return current object"); return curr; } @@ -405,6 +589,30 @@ JsonObject JsonObject::FindItem(const JsonFieldPath &jsonPath, int &errCode) con return item; } +// Compared with the non-powerMode mode, the node found by this function is an Array, and target is an object, +// if the Array contains the same object as the target, it can match this object in this mode. +JsonObject JsonObject::FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const +{ + if (jsonPath.empty()) { + JsonObject curr = JsonObject(); + curr.cjson_ = cjson_; + curr.caseSensitive_ = caseSensitive_; + curr.isOwner_ = false; + return curr; + } + + cJSON *findItem = MoveToPathPowerMode(cjson_, jsonPath, caseSensitive_); + if (findItem == nullptr) { + GLOGE("Find item failed. json field path not found."); + errCode = -E_JSON_PATH_NOT_EXISTS; + return {}; + } + JsonObject item; + item.caseSensitive_ = caseSensitive_; + item.cjson_ = findItem; + return item; +} + ValueObject JsonObject::GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const { JsonObject objGot = FindItem(jsonPath, errCode); @@ -415,7 +623,7 @@ ValueObject JsonObject::GetObjectByPath(const JsonFieldPath &jsonPath, int &errC return objGot.GetItemValue(); } -int JsonObject::DeleteItemOnTarget(const JsonFieldPath &path) +int JsonObject::DeleteItemDeeplyOnTarget(const JsonFieldPath &path) { if (path.empty()) { return -E_INVALID_ARGS; @@ -425,18 +633,24 @@ int JsonObject::DeleteItemOnTarget(const JsonFieldPath &path) JsonFieldPath patherPath = path; patherPath.pop_back(); - int errCode = E_OK; cJSON *nodeFather = MoveToPath(cjson_, patherPath, caseSensitive_); if (nodeFather == nullptr) { - GLOGE("Delete item failed, json field path not found."); return -E_JSON_PATH_NOT_EXISTS; } if (nodeFather->type == cJSON_Object) { if (caseSensitive_) { cJSON_DeleteItemFromObjectCaseSensitive(nodeFather, fieldName.c_str()); + if (nodeFather->child == nullptr && path.size() > 1) { + JsonFieldPath fatherPath(path.begin(), path.end() - 1); + DeleteItemDeeplyOnTarget(fatherPath); + } } else { cJSON_DeleteItemFromObject(nodeFather, fieldName.c_str()); + if (nodeFather->child == nullptr && path.size() > 1) { + JsonFieldPath fatherPath(path.begin(), path.end() - 1); + DeleteItemDeeplyOnTarget(fatherPath); + } } } else if (nodeFather->type == cJSON_Array) { if (!IsNumber(fieldName)) { @@ -444,6 +658,10 @@ int JsonObject::DeleteItemOnTarget(const JsonFieldPath &path) return -E_JSON_PATH_NOT_EXISTS; } cJSON_DeleteItemFromArray(nodeFather, std::stoi(fieldName)); + if (nodeFather->child == nullptr && path.size() > 1) { + JsonFieldPath fatherPath(path.begin(), path.end() - 1); + DeleteItemDeeplyOnTarget(fatherPath); + } } return E_OK; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp similarity index 82% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp index fedc5197a8c0a0160442e89c72dacb429d937812..79cbcc868989746ffd9ce8b7b552fd2261e90643 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp @@ -13,31 +13,29 @@ * limitations under the License. */ -#include "doc_errno.h" #include "kv_store_manager.h" + +#include "doc_errno.h" #include "log_print.h" #include "sqlite_store_executor_impl.h" #include "sqlite_utils.h" namespace DocumentDB { -constexpr const char *APP_ID = "APP_ID"; -constexpr const char *USER_ID = "USER_ID"; -constexpr const char *STORE_ID = "STORE_ID"; - -int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, KvStoreExecutor *&executor) +int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, bool isFirstOpen, + KvStoreExecutor *&executor) { if (executor != nullptr) { return -E_INVALID_ARGS; } sqlite3 *db = nullptr; - int errCode = SqliteStoreExecutor::CreateDatabase(path, config, db); + int errCode = SqliteStoreExecutorImpl::CreateDatabase(path, config, db); if (errCode != E_OK) { GLOGE("Get kv store failed. %d", errCode); return errCode; } - auto *sqliteExecutor = new (std::nothrow) SqliteStoreExecutor(db); + auto *sqliteExecutor = new (std::nothrow) SqliteStoreExecutorImpl(db); if (sqliteExecutor == nullptr) { sqlite3_close_v2(db); return -E_OUT_OF_MEMORY; @@ -47,6 +45,10 @@ int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, errCode = sqliteExecutor->GetDBConfig(oriConfigStr); if (errCode == -E_NOT_FOUND) { errCode = sqliteExecutor->SetDBConfig(config.ToString()); + if (errCode != E_OK) { + GLOGE("Set db config failed. %d", errCode); + goto END; + } } else if (errCode != E_OK) { goto END; } else { @@ -55,19 +57,17 @@ int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, GLOGE("Read db config failed. %d", errCode); goto END; } - if (config != oriDbConfig) { + if ((isFirstOpen ? (!config.CheckPersistenceEqual(oriDbConfig)) : (config != oriDbConfig))) { errCode = -E_INVALID_CONFIG_VALUE; GLOGE("Get kv store failed, db config changed. %d", errCode); goto END; } } - executor = sqliteExecutor; return E_OK; END: delete sqliteExecutor; - sqliteExecutor = nullptr; return errCode; } -} \ No newline at end of file +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39f34788a33f9b509b93761963f7a0aa9b082234 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp @@ -0,0 +1,412 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "sqlite_store_executor_impl.h" + +#include "check_common.h" +#include "db_constant.h" +#include "doc_errno.h" +#include "document_key.h" +#include "log_print.h" +#include "sqlite_utils.h" + +namespace DocumentDB { +constexpr const uint8_t KEY_TYPE = uint8_t(DocIdType::STRING); +int SqliteStoreExecutorImpl::CreateDatabase(const std::string &path, const DBConfig &config, sqlite3 *&db) +{ + if (db != nullptr) { + return -E_INVALID_ARGS; + } + + int errCode = SQLiteUtils::CreateDataBase(path, 0, db); + if (errCode != E_OK || db == nullptr) { + GLOGE("Open or create database failed. %d", errCode); + return errCode; + } + + std::string pageSizeSql = "PRAGMA page_size=" + std::to_string(config.GetPageSize() * 1024); + errCode = SQLiteUtils::ExecSql(db, pageSizeSql); + if (errCode != E_OK) { + GLOGE("Set db page size failed. %d", errCode); + goto END; + } + + errCode = SQLiteUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"); + if (errCode != E_OK) { + GLOGE("Set db journal_mode failed. %d", errCode); + goto END; + } + + errCode = SQLiteUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS grd_meta (key BLOB PRIMARY KEY, value BLOB);"); + if (errCode != E_OK) { + GLOGE("Create meta table failed. %d", errCode); + goto END; + } + + return E_OK; + +END: + sqlite3_close_v2(db); + db = nullptr; + return errCode; +} + +SqliteStoreExecutorImpl::SqliteStoreExecutorImpl(sqlite3 *handle) : dbHandle_(handle) {} + +SqliteStoreExecutorImpl::~SqliteStoreExecutorImpl() +{ + sqlite3_close_v2(dbHandle_); + dbHandle_ = nullptr; +} + +int SqliteStoreExecutorImpl::GetDBConfig(std::string &config) +{ + std::string dbConfigKeyStr = "DB_CONFIG"; + Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; + Value dbConfigVal; + int errCode = GetDataByKey("grd_meta", dbConfigKey, dbConfigVal); + config.assign(dbConfigVal.begin(), dbConfigVal.end()); + return errCode; +} + +int SqliteStoreExecutorImpl::SetDBConfig(const std::string &config) +{ + std::string dbConfigKeyStr = "DB_CONFIG"; + Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; + Value dbConfigVal = { config.begin(), config.end() }; + return PutData("grd_meta", dbConfigKey, dbConfigVal, false); // dont need to add Key type; +} + +int SqliteStoreExecutorImpl::StartTransaction() +{ + return SQLiteUtils::BeginTransaction(dbHandle_, TransactType::IMMEDIATE); +} + +int SqliteStoreExecutorImpl::Commit() +{ + return SQLiteUtils::CommitTransaction(dbHandle_); +} + +int SqliteStoreExecutorImpl::Rollback() +{ + return SQLiteUtils::RollbackTransaction(dbHandle_); +} + +int SqliteStoreExecutorImpl::PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType) +{ + if (dbHandle_ == nullptr) { + return -E_ERROR; + } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } + std::string sql = "INSERT OR REPLACE INTO '" + collName + "' VALUES (?,?);"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key, value](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + SQLiteUtils::BindBlobToStatement(stmt, 2, value); + return E_OK; + }, + nullptr); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Put data failed. err=%d", errCode); + if (errCode == -E_ERROR) { + GLOGE("Cant find the collection"); + return -E_INVALID_ARGS; + } + return errCode; + } + return E_OK; +} + +int SqliteStoreExecutorImpl::InsertData(const std::string &collName, Key &key, const Value &value, + bool isNeedAddKeyType) +{ + if (dbHandle_ == nullptr) { + return -E_ERROR; + } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } + std::string sql = "INSERT INTO '" + collName + "' VALUES (?,?);"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key, value](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + SQLiteUtils::BindBlobToStatement(stmt, 2, value); + return E_OK; + }, + nullptr); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Put data failed. err=%d", errCode); + if (errCode == -E_ERROR) { + GLOGE("have same ID before"); + return -E_DATA_CONFLICT; + } + return errCode; + } + return E_OK; +} + +int SqliteStoreExecutorImpl::GetDataByKey(const std::string &collName, Key &key, Value &value) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + int innerErrorCode = -E_NOT_FOUND; + std::string sql = "SELECT value FROM '" + collName + "' WHERE key=?;"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + return E_OK; + }, + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { + SQLiteUtils::GetColumnBlobValue(stmt, 0, value); + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + return innerErrorCode; +} + +int SqliteStoreExecutorImpl::GetDataById(const std::string &collName, Key &key, Value &value) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + key.push_back(KEY_TYPE); // Stitching ID type + int innerErrorCode = -E_NOT_FOUND; + std::string sql = "SELECT value FROM '" + collName + "' WHERE key=?;"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + return E_OK; + }, + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { + SQLiteUtils::GetColumnBlobValue(stmt, 0, value); + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + return innerErrorCode; +} + +std::string GeneralInsertSql(const std::string &collName, Key &key, int isIdExist) +{ + std::string sqlEqual = "SELECT key, value FROM '" + collName + "' WHERE key=?;"; + std::string sqlOrder = "SELECT key, value FROM '" + collName + "' ORDER BY KEY;"; + std::string sqlLarger = "SELECT key, value FROM '" + collName + "' WHERE key>?;"; + if (isIdExist) { + return sqlEqual; + } else { + return (key.empty()) ? sqlOrder : sqlLarger; + } +} + +void AssignValueToData(std::string &keyStr, std::string &valueStr, std::pair &values, + int &innerErrorCode, bool &isMatchOneData) +{ + keyStr.pop_back(); // get id from really key. + values.first = keyStr; + values.second = valueStr; + innerErrorCode = E_OK; + isMatchOneData = true; // this args work in ExecSql fuction +} + +int SqliteStoreExecutorImpl::GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + Value keyResult; + Value valueResult; + bool isFindMatch = false; + int innerErrorCode = -E_NOT_FOUND; + std::string sql = GeneralInsertSql(collName, key, isIdExist); + key.push_back(KEY_TYPE); + std::string keyStr(key.begin(), key.end()); + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + if (!key.empty()) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + } + return E_OK; + }, + [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt, + bool &isMatchOneData) { + SQLiteUtils::GetColumnBlobValue(stmt, 0, keyResult); + SQLiteUtils::GetColumnBlobValue(stmt, 1, valueResult); + std::string keyStr(keyResult.begin(), keyResult.end()); + std::string valueStr(valueResult.begin(), valueResult.end()); + JsonObject srcObj = JsonObject::Parse(valueStr, innerErrorCode, true); + if (innerErrorCode != E_OK) { + GLOGE("srcObj Parsed failed"); + return innerErrorCode; + } + if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, innerErrorCode)) { + isFindMatch = true; // this args work in this function + (void)AssignValueToData(keyStr, valueStr, values, innerErrorCode, isMatchOneData); + return E_OK; // match count; + } + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + if (!isFindMatch) { + return -E_NOT_FOUND; + } + return innerErrorCode; +} + +int SqliteStoreExecutorImpl::DelData(const std::string &collName, Key &key) +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + key.push_back(KEY_TYPE); + int errCode = 0; + Value valueRet; + if (GetDataByKey(collName, key, valueRet) != E_OK) { + return -E_NO_DATA; + } + std::string sql = "DELETE FROM '" + collName + "' WHERE key=?;"; + errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + return E_OK; + }, + nullptr); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Delete data failed. err=%d", errCode); + if (errCode == -E_ERROR) { + GLOGE("Cant find the collection"); + return -E_NO_DATA; + } + } + return errCode; +} + +int SqliteStoreExecutorImpl::CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) +{ + if (dbHandle_ == nullptr) { + return -E_ERROR; + } + std::string collName = DBConstant::COLL_PREFIX + name; + int errCode = E_OK; + bool isExists = IsCollectionExists(collName, errCode); + if (errCode != E_OK) { + return errCode; + } + + if (isExists) { + GLOGW("[sqlite executor] Create collection failed, collection already exists."); + return ignoreExists ? E_OK : -E_COLLECTION_CONFLICT; + } + + std::string sql = "CREATE TABLE IF NOT EXISTS '" + collName + "' (key BLOB PRIMARY KEY, value BLOB);"; + errCode = SQLiteUtils::ExecSql(dbHandle_, sql); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Create collection failed. err=%d", errCode); + return errCode; + } + + errCode = SetCollectionOption(name, option); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Set collection option failed. err=%d", errCode); + } + return errCode; +} + +int SqliteStoreExecutorImpl::DropCollection(const std::string &name, bool ignoreNonExists) +{ + if (dbHandle_ == nullptr) { + return -E_ERROR; + } + + std::string collName = DBConstant::COLL_PREFIX + name; + if (!ignoreNonExists) { + int errCode = E_OK; + bool isExists = IsCollectionExists(collName, errCode); + if (errCode != E_OK) { + return errCode; + } + if (!isExists) { + GLOGE("[sqlite executor] Drop collection failed, collection not exists."); + return -E_INVALID_ARGS; + } + } + + std::string sql = "DROP TABLE IF EXISTS '" + collName + "';"; + int errCode = SQLiteUtils::ExecSql(dbHandle_, sql); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Drop collection failed. err=%d", errCode); + } + return errCode; +} + +bool SqliteStoreExecutorImpl::IsCollectionExists(const std::string &name, int &errCode) +{ + bool isExists = false; + std::string sql = "SELECT tbl_name FROM sqlite_master WHERE tbl_name=?;"; + errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [name](sqlite3_stmt *stmt) { + SQLiteUtils::BindTextToStatement(stmt, 1, name); + return E_OK; + }, + [&isExists](sqlite3_stmt *stmt, bool &isMatchOneData) { + isExists = true; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("Check collection exist failed. %d", errCode); + } + return isExists; +} + +int SqliteStoreExecutorImpl::SetCollectionOption(const std::string &name, const std::string &option) +{ + std::string collOptKeyStr = "COLLECTION_OPTION_" + name; + Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; + Value collOptVal = { option.begin(), option.end() }; + return PutData("grd_meta", collOptKey, collOptVal, false); // dont need to add key type; +} + +int SqliteStoreExecutorImpl::CleanCollectionOption(const std::string &name) +{ + std::string collOptKeyStr = "COLLECTION_OPTION_" + name; + Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; + return DelData("grd_meta", collOptKey); +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h similarity index 55% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h index bc6857b83a5263998a700cffb28a55b6b111e672..8da9ed30f3ddfe6ac1d7b71e96daf749665c73d6 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h @@ -17,34 +17,43 @@ #define SQLITE_STORE_EXECUTOR_IMPL_H #include "db_config.h" +#include "json_common.h" #include "kv_store_executor.h" #include "sqlite3.h" namespace DocumentDB { -class SqliteStoreExecutor : public KvStoreExecutor { +class SqliteStoreExecutorImpl : public KvStoreExecutor { public: static int CreateDatabase(const std::string &path, const DBConfig &config, sqlite3 *&db); - SqliteStoreExecutor(sqlite3 *handle); - ~SqliteStoreExecutor() override; + SqliteStoreExecutorImpl() = default; + explicit SqliteStoreExecutorImpl(sqlite3 *handle); + ~SqliteStoreExecutorImpl() override; int GetDBConfig(std::string &config); int SetDBConfig(const std::string &config); - int PutData(const std::string &collName, const Key &key, const Value &value) override; - int GetData(const std::string &collName, const Key &key, Value &value) const override; - int DelData(const std::string &collName, const Key &key) override; + int StartTransaction() override; + int Commit() override; + int Rollback() override; - int CreateCollection(const std::string &name, bool ignoreExists) override; + int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int GetDataByKey(const std::string &collName, Key &key, Value &value) const override; + int GetDataById(const std::string &collName, Key &key, Value &value) const override; + int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const override; + int DelData(const std::string &collName, Key &key) override; + + int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) override; int DropCollection(const std::string &name, bool ignoreNonExists) override; bool IsCollectionExists(const std::string &name, int &errCode) override; - int GetCollectionOption(const std::string &name, std::string &option) override; int SetCollectionOption(const std::string &name, const std::string &option) override; int CleanCollectionOption(const std::string &name) override; private: sqlite3 *dbHandle_ = nullptr; }; -} // DocumentDB +} // namespace DocumentDB #endif // SQLITE_STORE_EXECUTOR_IMPL_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp similarity index 82% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp index 30c0d095134e5bf0687fc5ac7ea20c4b6cd7a27e..2c56227d361895f44d5ae22ebcb13497b983a6c6 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp @@ -14,12 +14,14 @@ */ #include "sqlite_utils.h" +#include + #include "doc_errno.h" #include "log_print.h" namespace DocumentDB { -const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit TODO:: check blob size -const int MAX_TEXT_READ_SIZE = 5 * 1024 * 1024; // 5M limit +const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit +const int BUSY_TIMEOUT_MS = 3000; // 3000ms for sqlite busy timeout. const std::string BEGIN_SQL = "BEGIN TRANSACTION"; const std::string BEGIN_IMMEDIATE_SQL = "BEGIN IMMEDIATE TRANSACTION"; const std::string COMMIT_SQL = "COMMIT TRANSACTION"; @@ -33,28 +35,50 @@ int MapSqliteError(int errCode) return E_OK; case SQLITE_PERM: case SQLITE_CANTOPEN: + return -E_INVALID_ARGS; case SQLITE_READONLY: return -E_FILE_OPERATION; + case SQLITE_NOTADB: + return -E_INVALID_FILE_FORMAT; + case SQLITE_BUSY: + return -E_RESOURCE_BUSY; default: return -E_ERROR; } } -} + +std::mutex g_logConfigMutex; +bool g_configLog = false; +} // namespace void SQLiteUtils::SqliteLogCallback(void *data, int err, const char *msg) { - GLOGD("[SQLite] err=%d sys=%d %s msg=%s", err, errno, sqlite3_errstr(err), msg); + GLOGD("[SQLite] err=%d sys=%d %s", err, errno, sqlite3_errstr(err)); } int SQLiteUtils::CreateDataBase(const std::string &path, int flag, sqlite3 *&db) { + { + std::lock_guard lock(g_logConfigMutex); + if (!g_configLog) { + sqlite3_config(SQLITE_CONFIG_LOG, &SqliteLogCallback, nullptr); + g_configLog = true; + } + } + int errCode = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr); if (errCode != SQLITE_OK) { - GLOGE("Open database [%s] failed. %d", path.c_str(), errCode); + GLOGE("Open database failed. %d", errCode); if (db != nullptr) { (void)sqlite3_close_v2(db); db = nullptr; } + return MapSqliteError(errCode); + } + + errCode = sqlite3_busy_timeout(db, BUSY_TIMEOUT_MS); + if (errCode != SQLITE_OK) { + GLOGE("Set busy timeout failed:%d", errCode); } return MapSqliteError(errCode); } @@ -74,7 +98,7 @@ int SQLiteUtils::GetStatement(sqlite3 *db, const std::string &sql, sqlite3_stmt if (errCode != SQLITE_OK) { GLOGE("Prepare SQLite statement failed:%d", errCode); (void)SQLiteUtils::ResetStatement(statement, true); - return errCode; + return MapSqliteError(errCode); } if (statement == nullptr) { @@ -135,12 +159,8 @@ int SQLiteUtils::BindBlobToStatement(sqlite3_stmt *statement, int index, const s if (value.empty()) { errCode = sqlite3_bind_zeroblob(statement, index, -1); // -1 for zero-length blob. } else { - errCode = sqlite3_bind_blob(statement, index, static_cast(value.data()), - value.size(), SQLITE_TRANSIENT); - } - - if (errCode != SQLITE_OK) { - GLOGE("[SQLiteUtil][Bind blob] Failed to bind the value:%d", errCode); + errCode = sqlite3_bind_blob(statement, index, static_cast(value.data()), value.size(), + SQLITE_TRANSIENT); } return errCode; } @@ -184,29 +204,6 @@ int SQLiteUtils::BindTextToStatement(sqlite3_stmt *statement, int index, const s return E_OK; } -int SQLiteUtils::GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value) -{ - if (statement == nullptr) { - return -E_INVALID_ARGS; - } - - int valSize = sqlite3_column_bytes(statement, index); - if (valSize < 0 || valSize > MAX_TEXT_READ_SIZE) { - GLOGW("[SQLiteUtils][Column text] size over limit:%d", valSize); - value.resize(MAX_TEXT_READ_SIZE + 1); // Reset value size to invalid - return E_OK; // Return OK for continue get data, but value is invalid - } - - const unsigned char *val = sqlite3_column_text(statement, index); - if (valSize == 0 || val == nullptr) { - value = {}; - } else { - value = std::string(reinterpret_cast(val)); - } - - return E_OK; -} - int SQLiteUtils::BeginTransaction(sqlite3 *db, TransactType type) { if (type == TransactType::IMMEDIATE) { @@ -242,19 +239,19 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql) return MapSqliteError(errCode); } -int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback) +int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, + const std::function &resultCallback) { if (db == nullptr || sql.empty()) { return -E_INVALID_ARGS; } bool bindFinish = true; sqlite3_stmt *stmt = nullptr; + bool isMatchOneData = false; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { goto END; } - do { if (bindCallback) { errCode = bindCallback(stmt); @@ -267,12 +264,14 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::functio while (true) { errCode = SQLiteUtils::StepWithRetry(stmt); if (errCode == SQLITE_DONE) { - errCode = E_OK; // Step finished break; } else if (errCode != SQLITE_ROW) { goto END; // Step return error } - if (resultCallback != nullptr && ((errCode = resultCallback(stmt)) != E_OK)) { + if (resultCallback != nullptr) { // find one data, stop stepping. + errCode = resultCallback(stmt, isMatchOneData); + } + if (resultCallback != nullptr && ((errCode != E_OK) || isMatchOneData)) { goto END; } } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h similarity index 88% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h index 4dcf5b1b977020dd35d9ed63ab1b1775eaf3ac1a..88cc77efd2f05fb8ffb991d26a0b4cb206ad6d7d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_utils.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h @@ -20,7 +20,7 @@ #include #include -#include "sqlite3.h" +#include "sqlite3sym.h" namespace DocumentDB { enum class TransactType { @@ -40,15 +40,14 @@ public: static int GetColumnBlobValue(sqlite3_stmt *statement, int index, std::vector &value); static int BindTextToStatement(sqlite3_stmt *statement, int index, const std::string &value); - static int GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value); static int BeginTransaction(sqlite3 *db, TransactType type = TransactType::DEFERRED); static int CommitTransaction(sqlite3 *db); static int RollbackTransaction(sqlite3 *db); static int ExecSql(sqlite3 *db, const std::string &sql); - static int ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback); + static int ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, + const std::function &resultCallback); private: static void SqliteLogCallback(void *data, int err, const char *msg); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..c8a7cab5bef9293c572812296e3c230be15dd291 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn @@ -0,0 +1,182 @@ +# 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("//build/test.gni") + +module_output_path = "datamgr_service/gaussdb_rd" + +############################################################################### +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "../../include", + "../../src/common/include", + "../../src/executor/include", + "../../src/executor/document", + "../../src/oh_adapter/include", + "../../src/oh_adapter/src", + "../../src/interface/include", + + "common", + ] + + defines = [ + "SQLITE_ENABLE_SNAPSHOT", + "SQLITE_HAS_CODEC", + "SQLITE_ENABLE_JSON1", + "USING_HILOG_LOGGER", + "USE_SQLITE_SYMBOLS", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", + ] +} + +############################################################################### +ohos_source_set("src_file") { + testonly = true + + sources = [ + "../../src/common/src/collection_option.cpp", + "../../src/common/src/db_config.cpp", + "../../src/common/src/db_constant.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/document/check_common.cpp", + "../../src/executor/document/grd_document_api.cpp", + "../../src/executor/document/grd_resultset_api.cpp", + "../../src/interface/src/collection.cpp", + "../../src/interface/src/doc_errno.cpp", + "../../src/interface/src/document_key.cpp", + "../../src/interface/src/document_store.cpp", + "../../src/interface/src/document_store_manager.cpp", + "../../src/interface/src/projection_tree.cpp", + "../../src/interface/src/result_set.cpp", + "../../src/interface/src/result_set_common.cpp", + "../../src/oh_adapter/src/json_object.cpp", + "../../src/oh_adapter/src/kv_store_manager.cpp", + "../../src/oh_adapter/src/sqlite_store_executor_impl.cpp", + "../../src/oh_adapter/src/sqlite_utils.cpp", + "common/documentdb_test_utils.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gtest_main", + "//third_party/sqlite:sqlite", + ] + + configs += [ "//third_party/cJSON:cJSON_config" ] + ldflags = [ "-Wl,--exclude-libs,ALL" ] + deps += [ "//third_party/cJSON:cjson" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + + subsystem_name = "distributeddatamgr" + part_name = "datamgr_service" +} + +template("gaussdb_rd_unittest") { + ohos_unittest(target_name) { + forward_variables_from(invoker, "*") + module_out_path = module_output_path + if (!defined(deps)) { + deps = [] + } + if (!defined(external_deps)) { + external_deps = [] + } + configs = [ ":module_private_config" ] + deps += [ + ":src_file", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//third_party/sqlite:sqlite", + ] + configs += [ "//third_party/cJSON:cJSON_config" ] + ldflags = [ "-Wl,--exclude-libs,ALL" ] + deps += [ + "//third_party/cJSON:cjson", + "//third_party/openssl:libcrypto_shared", + ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + } +} + +gaussdb_rd_unittest("DocumentDBApiTest") { + sources = [ "api/documentdb_api_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBCollectionTest") { + sources = [ "api/documentdb_collection_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBDataTest") { + sources = [ "api/documentdb_data_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBJsonCommonTest") { + sources = [ "oh_adapter/documentdb_json_common_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBJsonObjectTest") { + sources = [ "oh_adapter/documentdb_jsonobject_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBInsertTest") { + sources = [ "api/documentdb_insert_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBFindTest") { + sources = [ "api/documentdb_find_test.cpp" ] +} + +gaussdb_rd_unittest("DocumentDBDeleteTest") { + sources = [ "api/documentdb_delete_test.cpp" ] +} + +############################################################################### +group("unittest") { + testonly = true + deps = [ "//third_party/googletest:gmock" ] + + deps += [ + ":DocumentDBApiTest", + ":DocumentDBCollectionTest", + ":DocumentDBDataTest", + ":DocumentDBDeleteTest", + ":DocumentDBFindTest", + ":DocumentDBInsertTest", + ":DocumentDBJsonCommonTest", + ":DocumentDBJsonObjectTest", + ] +} + +############################################################################### + +group("document_fuzztest") { + testonly = true + deps = [] + deps += [] +} +############################################################################### diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_api_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp similarity index 65% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_api_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp index 382fe5ef71dd3a0cd036b1b37e1141412748e7f2..93358885e594aa3f5425834b4d70f9c406961985 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_api_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp @@ -16,17 +16,19 @@ #include #include "doc_errno.h" +#include "doc_limit.h" #include "documentdb_test_utils.h" -#include "log_print.h" #include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" #include "grd_document/grd_document_api.h" +#include "log_print.h" #include "sqlite_utils.h" using namespace DocumentDB; using namespace testing::ext; using namespace DocumentDBUnitTest; +namespace { class DocumentDBApiTest : public testing::Test { public: static void SetUpTestCase(void); @@ -35,17 +37,11 @@ public: void TearDown(); }; -void DocumentDBApiTest::SetUpTestCase(void) -{ -} +void DocumentDBApiTest::SetUpTestCase(void) {} -void DocumentDBApiTest::TearDownTestCase(void) -{ -} +void DocumentDBApiTest::TearDownTestCase(void) {} -void DocumentDBApiTest::SetUp(void) -{ -} +void DocumentDBApiTest::SetUp(void) {} void DocumentDBApiTest::TearDown(void) { @@ -70,8 +66,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest001, TestSize.Level0) EXPECT_EQ(GRD_CreateCollection(db, "student", "", 0), GRD_OK); - EXPECT_EQ(GRD_UpSertDoc(db, "student", "10001", R""({"name":"Tom","age":23})"", 0), GRD_OK); - EXPECT_EQ(GRD_UpSertDoc(db, "student", "10001", R""({"name":"Tom","age":23})"", 0), GRD_OK); + EXPECT_EQ(GRD_UpsertDoc(db, "student", R""({"_id":"10001"})"", R""({"name":"Tom", "age":23})"", 0), 1); EXPECT_EQ(GRD_DropCollection(db, "student", 0), GRD_OK); @@ -100,13 +95,58 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest002, TestSize.Level0) EXPECT_EQ(status, GRD_OK); EXPECT_NE(db, nullptr); + status = GRD_DBClose(db, GRD_DB_CLOSE); + EXPECT_EQ(status, GRD_OK); + status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); - EXPECT_EQ(status, GRD_INVALID_ARGS); + EXPECT_EQ(status, GRD_OK); status = GRD_DBClose(db, GRD_DB_CLOSE); EXPECT_EQ(status, GRD_OK); } +HWTEST_F(DocumentDBApiTest, OpenDBTest003, TestSize.Level0) +{ + std::string path = "./document.db"; + GRD_DB *db = nullptr; + int status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_OK); + EXPECT_NE(db, nullptr); + GLOGD("Open DB test 003: status: %d", status); + + GRD_DB *db1 = nullptr; + status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db1); + EXPECT_EQ(status, GRD_OK); + EXPECT_NE(db1, nullptr); + + status = GRD_DBClose(db, GRD_DB_CLOSE); + EXPECT_EQ(status, GRD_OK); + + status = GRD_DBClose(db1, GRD_DB_CLOSE); + EXPECT_EQ(status, GRD_OK); +} + +/** + * @tc.name: OpenDBTest004 + * @tc.desc: Test open document db while db is not db file + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhuwentao + */ +HWTEST_F(DocumentDBApiTest, OpenDBTest004, TestSize.Level0) +{ + std::string path = "./test.txt"; + FILE *fp; + fp = fopen("./test.txt", "w"); + fwrite("hello", 5, 5, fp); + fclose(fp); + GRD_DB *db = nullptr; + int status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_ONLY, &db); + EXPECT_EQ(status, GRD_INVALID_FILE_FORMAT); + + DocumentDBTestUtils::RemoveTestDbFiles(path); +} + /** * @tc.name: OpenDBPathTest001 * @tc.desc: Test open document db with NULL path @@ -117,11 +157,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBPathTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::vector invalidPath = { - nullptr, - "", - "/a/b/c/" - }; + std::vector invalidPath = { nullptr, "" }; for (auto path : invalidPath) { GLOGD("OpenDBPathTest001: open db with path: %s", path); int status = GRD_DBOpen(path, nullptr, GRD_DB_OPEN_CREATE, &db); @@ -144,6 +180,21 @@ HWTEST_F(DocumentDBApiTest, OpenDBPathTest002, TestSize.Level0) EXPECT_EQ(status, GRD_FAILED_FILE_OPERATION); } +/** + * @tc.name: OpenDBPathTest004 + * @tc.desc: call GRD_DBOpen, input dbFile as existed menu + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBPathTest004, TestSize.Level0) +{ + GRD_DB *db = nullptr; + std::string pathNoPerm = "../build"; + int status = GRD_DBOpen(pathNoPerm.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); +} + /** * @tc.name: OpenDBConfigTest001 * @tc.desc: Test open document db with invalid config option @@ -154,8 +205,8 @@ HWTEST_F(DocumentDBApiTest, OpenDBPathTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; - const int MAX_JSON_LEN = 512 * 1024; + std::string path = "./document.db"; + const int MAX_JSON_LEN = 1024 * 1024; std::string configStr = std::string(MAX_JSON_LEN, 'a'); int status = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OVER_LIMIT); @@ -171,7 +222,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigTest002, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), "{aa}", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_INVALID_FORMAT); } @@ -186,11 +237,70 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigTest003, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), R""({"notSupport":123})"", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_INVALID_ARGS); } +/** + * @tc.name: OpenDBConfigTest004 + * @tc.desc: call GRD_DBOpen, input the value's length of configStr is 1024K + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ + +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. input the value's length of configStr is 1024 k(not contained '\0') + */ + GRD_DB *db = nullptr; + std::string part1 = "{ \"pageSize\": \" "; + std::string part2 = "\" }"; + std::string path = "./document.db"; + std::string val = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size(), 'k'); + std::string configStr = part1 + val + part2; + int ret = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_OVER_LIMIT); + /** + * @tc.steps:step2. input the value's length of configStr is 1024 k(contained '\0') + */ + std::string val2 = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size() - 1, 'k'); + std::string configStr2 = part1 + val2 + part2 + "\0"; + ret = GRD_DBOpen(path.c_str(), configStr2.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_INVALID_ARGS); +} + +/** + * @tc.name: OpenDBConfigTest005 + * @tc.desc: Verify open db with different configStr connection when first connection not close, + * return GRD_INVALID_CONFIG_VALUE. + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. call GRD_DBOPEN to create a db with connection1. + * @tc.expected:step1. GRD_OK. + */ + const char *configStr = R"({"pageSize":64, "bufferPoolSize": 4096})"; + GRD_DB *db1 = nullptr; + std::string path = "./document.db"; + int result = GRD_DBOpen(path.c_str(), configStr, GRD_DB_OPEN_CREATE, &db1); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps:step2. connection2 call GRD_DBOpen to open the db with the different configStr. + * @tc.expected:step2. return GRD_CONFIG_OPTION_MISMATCH. + */ + const char *configStr_2 = R"({"pageSize":4})"; + GRD_DB *db2 = nullptr; + result = GRD_DBOpen(path.c_str(), configStr_2, GRD_DB_OPEN_ONLY, &db2); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + ASSERT_EQ(GRD_DBClose(db1, GRD_DB_CLOSE), GRD_OK); +} /** * @tc.name: OpenDBConfigMaxConnNumTest001 * @tc.desc: Test open document db with invalid config item maxConnNum @@ -201,7 +311,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest003, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; std::vector configList = { R""({"maxConnNum":0})"", @@ -210,7 +320,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest001, TestSize.Level0) R""({"maxConnNum":1000000007})"", R""({"maxConnNum":"16"})"", R""({"maxConnNum":{"value":17}})"", - R""({"maxConnNum":[16,17,18]})"", + R""({"maxConnNum":[16, 17, 18]})"", }; for (const auto &config : configList) { GLOGD("OpenDBConfigMaxConnNumTest001: test with config:%s", config.c_str()); @@ -229,7 +339,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest002, TestSize.Level1) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; for (int i = 16; i <= 1024; i++) { std::string config = "{\"maxConnNum\":" + std::to_string(i) + "}"; @@ -255,20 +365,20 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest002, TestSize.Level1) HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest003, TestSize.Level1) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; std::string config = R""({"maxConnNum":16})""; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); - status = GRD_DBClose(db, GRD_DB_CLOSE); - EXPECT_EQ(status, GRD_OK); - db = nullptr; - + GRD_DB *db1 = nullptr; config = R""({"maxConnNum":17})""; - status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); + status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db1); EXPECT_EQ(status, GRD_INVALID_ARGS); + status = GRD_DBClose(db, GRD_DB_CLOSE); + EXPECT_EQ(status, GRD_OK); + db = nullptr; DocumentDBTestUtils::RemoveTestDbFiles(path); } @@ -281,7 +391,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest003, TestSize.Level1) */ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest004, TestSize.Level1) { - std::string path= "./document.db"; + std::string path = "./document.db"; int maxCnt = 16; std::string config = "{\"maxConnNum\":" + std::to_string(maxCnt) + "}"; @@ -291,6 +401,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest004, TestSize.Level1) GRD_DB *db = nullptr; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); + EXPECT_NE(db, nullptr); dbList.push_back(db); } @@ -298,6 +409,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest004, TestSize.Level1) int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); EXPECT_NE(db, nullptr); + dbList.push_back(db); for (auto *it : dbList) { status = GRD_DBClose(it, GRD_DB_CLOSE); @@ -317,7 +429,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest004, TestSize.Level1) HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; std::vector configList = { R""({"pageSize":0})"", @@ -326,7 +438,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest001, TestSize.Level0) R""({"pageSize":1000000007})"", R""({"pageSize":"4"})"", R""({"pageSize":{"value":8}})"", - R""({"pageSize":[16,32,64]})"", + R""({"pageSize":[16, 32, 64]})"", }; for (const auto &config : configList) { GLOGD("OpenDBConfigPageSizeTest001: test with config:%s", config.c_str()); @@ -344,9 +456,8 @@ int GetDBPageSize(const std::string &path) if (db == nullptr) { return 0; } - int pageSize = 0; - SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt) { + SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt, bool &isMatchOneData) { pageSize = sqlite3_column_int(stmt, 0); return E_OK; }); @@ -354,7 +465,7 @@ int GetDBPageSize(const std::string &path) sqlite3_close_v2(db); return pageSize; } -} +} // namespace /** * @tc.name: OpenDBConfigPageSizeTest002 @@ -366,9 +477,9 @@ int GetDBPageSize(const std::string &path) HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest002, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; - for (int size : {4, 8, 16, 32, 64}) { + for (int size : { 4, 8, 16, 32, 64 }) { std::string config = "{\"pageSize\":" + std::to_string(size) + "}"; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); @@ -392,7 +503,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest003, TestSize.Level1) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; std::string config = R""({"pageSize":4})""; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); @@ -419,9 +530,9 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest003, TestSize.Level1) HWTEST_F(DocumentDBApiTest, OpenDBConfigRedoFlushTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; - for (int flush : {0, 1}) { + for (int flush : { 0, 1 }) { std::string config = "{\"redoFlushByTrx\":" + std::to_string(flush) + "}"; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); @@ -444,13 +555,65 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigRedoFlushTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBConfigRedoFlushTest002, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; std::string config = R""({"redoFlushByTrx":3})""; int status = GRD_DBOpen(path.c_str(), config.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_INVALID_ARGS); } +/** + * @tc.name: OpenDBConfigBufferPoolTest001 + * @tc.desc: Test open document db with invalid config item bufferPoolSize + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBApiTest, OpenDBConfigBufferPoolTest001, TestSize.Level0) +{ + GRD_DB *db = nullptr; + std::string path = "./document.db"; + + int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "bufferPoolSize":4096})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_DBClose(db, 0), GRD_OK); + + status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "bufferPoolSize":4095})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); + + status = GRD_DBOpen(path.c_str(), R""({"bufferPoolSize":1023})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); + + status = GRD_DBOpen(path.c_str(), R""({"bufferPoolSize":4194304})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); +} + +/** + * @tc.name: OpenDBConfigPubBuffTest001 + * @tc.desc: Test open document db with invalid config item redopubbufsize + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBApiTest, OpenDBConfigPubBuffTest001, TestSize.Level0) +{ + GRD_DB *db = nullptr; + std::string path = "./document.db"; + + int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "redopubbufsize":4033})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_DBClose(db, 0), GRD_OK); + + status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "redopubbufsize":4032})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); + + status = GRD_DBOpen(path.c_str(), R""({"redopubbufsize":255})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); + + status = GRD_DBOpen(path.c_str(), R""({"redopubbufsize":16385})"", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); +} + /** * @tc.name: OpenDBFlagTest001 * @tc.desc: Test open document db with invalid flag @@ -461,14 +624,9 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigRedoFlushTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBFlagTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; - std::vector invaldFlag = { - GRD_DB_OPEN_CHECK_FOR_ABNORMAL | GRD_DB_OPEN_CHECK, - GRD_DB_OPEN_CREATE | GRD_DB_OPEN_CHECK_FOR_ABNORMAL | GRD_DB_OPEN_CHECK, - 0x08, - 0xffff, - UINT32_MAX - }; + std::string path = "./document.db"; + std::vector invaldFlag = { GRD_DB_OPEN_CHECK_FOR_ABNORMAL | GRD_DB_OPEN_CHECK, + GRD_DB_OPEN_CREATE | GRD_DB_OPEN_CHECK_FOR_ABNORMAL | GRD_DB_OPEN_CHECK, 0x08, 0xffff, UINT32_MAX }; for (unsigned int flag : invaldFlag) { GLOGD("OpenDBFlagTest001: open doc db with flag %u", flag); int status = GRD_DBOpen(path.c_str(), "", flag, &db); @@ -486,7 +644,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBFlagTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBFlagTest002, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), "", GRD_DB_OPEN_ONLY, &db); EXPECT_EQ(status, GRD_INVALID_ARGS); @@ -549,7 +707,7 @@ HWTEST_F(DocumentDBApiTest, CloseDBTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, CloseDBFlagTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), "", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); ASSERT_NE(db, nullptr); @@ -571,13 +729,11 @@ HWTEST_F(DocumentDBApiTest, CloseDBFlagTest001, TestSize.Level0) HWTEST_F(DocumentDBApiTest, CloseDBFlagTest002, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), "", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); ASSERT_NE(db, nullptr); - // TODO: open result set - status = GRD_DBClose(db, GRD_DB_CLOSE_IGNORE_ERROR); EXPECT_EQ(status, GRD_OK); db = nullptr; @@ -595,17 +751,12 @@ HWTEST_F(DocumentDBApiTest, CloseDBFlagTest002, TestSize.Level0) HWTEST_F(DocumentDBApiTest, CloseDBFlagTest003, TestSize.Level0) { GRD_DB *db = nullptr; - std::string path= "./document.db"; + std::string path = "./document.db"; int status = GRD_DBOpen(path.c_str(), "", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); ASSERT_NE(db, nullptr); - std::vector invaldFlag = { - 0x02, - 0x03, - 0xffff, - UINT32_MAX - }; + std::vector invaldFlag = { 0x02, 0x03, 0xffff, UINT32_MAX }; for (unsigned int flag : invaldFlag) { GLOGD("CloseDBFlagTest003: close doc db with flag %u", flag); status = GRD_DBClose(db, flag); @@ -617,4 +768,37 @@ HWTEST_F(DocumentDBApiTest, CloseDBFlagTest003, TestSize.Level0) db = nullptr; DocumentDBTestUtils::RemoveTestDbFiles(path); -} \ No newline at end of file +} + +/** + * @tc.name: FlushDBTest001 + * @tc.desc: Test flush document db + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBApiTest, FlushDBTest001, TestSize.Level0) +{ + EXPECT_EQ(GRD_Flush(nullptr, GRD_DB_FLUSH_ASYNC), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_Flush(nullptr, GRD_DB_FLUSH_SYNC), GRD_INVALID_ARGS); + + GRD_DB *db = nullptr; + std::string path = "./document.db"; + int status = GRD_DBOpen(path.c_str(), "", GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_OK); + ASSERT_NE(db, nullptr); + + EXPECT_EQ(GRD_Flush(db, GRD_DB_FLUSH_ASYNC), GRD_OK); + EXPECT_EQ(GRD_Flush(db, GRD_DB_FLUSH_SYNC), GRD_OK); + std::vector invalidFlags = { 2, 4, 8, 512, 1024, UINT32_MAX }; + for (auto flags : invalidFlags) { + EXPECT_EQ(GRD_Flush(db, flags), GRD_INVALID_ARGS); + } + + status = GRD_DBClose(db, GRD_DB_CLOSE); + EXPECT_EQ(status, GRD_OK); + db = nullptr; + + DocumentDBTestUtils::RemoveTestDbFiles(path); +} +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_collection_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp similarity index 86% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_collection_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp index a15df4df50029f45055142b9ed59b2bc9d47c19f..04431be400ba2e7d2c2ad9a79cc68edcf37f4695 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_collection_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp @@ -17,10 +17,10 @@ #include "doc_errno.h" #include "documentdb_test_utils.h" -#include "log_print.h" #include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" #include "grd_document/grd_document_api.h" +#include "log_print.h" #include "sqlite_utils.h" using namespace DocumentDB; @@ -30,7 +30,6 @@ using namespace DocumentDBUnitTest; namespace { std::string g_path = "./document.db"; GRD_DB *g_db = nullptr; -} class DocumentDBCollectionTest : public testing::Test { public: @@ -40,13 +39,9 @@ public: void TearDown(); }; -void DocumentDBCollectionTest::SetUpTestCase(void) -{ -} +void DocumentDBCollectionTest::SetUpTestCase(void) {} -void DocumentDBCollectionTest::TearDownTestCase(void) -{ -} +void DocumentDBCollectionTest::TearDownTestCase(void) {} void DocumentDBCollectionTest::SetUp(void) { @@ -103,12 +98,7 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest002, TestSize.Level0) EXPECT_EQ(GRD_DropCollection(g_db, it, 0), GRD_INVALID_ARGS); } - std::vector invalidNameFormat = { - "GRD_123", - "grd_123", - "GM_SYS_123", - "gm_sys_123" - }; + std::vector invalidNameFormat = { "GRD_123", "grd_123", "GM_SYS_123", "gm_sys_123" }; for (auto *it : invalidNameFormat) { GLOGD("CollectionTest002: create collection with name: %s", it); @@ -127,15 +117,9 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest002, TestSize.Level0) HWTEST_F(DocumentDBCollectionTest, CollectionTest003, TestSize.Level0) { string overLenName(MAX_COLLECTION_LEN - 1, 'a'); - std::vector validName = { - "123", - "&^%@", - "中文字符", - "sqlite_master", - "NULL", - "SELECT", - overLenName.c_str() - }; + std::vector validName = { "123", "&^%@", "中文字符", "sqlite_master", "NULL", "SELECT", "CREATE", + "student/", "student'", "student\"", "student[", "student]", "student%", "student&", "student_", "student(", + "student)", overLenName.c_str() }; for (auto *it : validName) { GLOGD("CollectionTest003: create collection with name: %s", it); @@ -173,7 +157,7 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest005, TestSize.Level0) R""({"maxDoc":0})"", R""({"maxDoc":"123"})"", R""({"maxDoc":{"value":1024}})"", - R""({"maxDoc":[1,2,4,8]})"", + R""({"maxDoc":[1, 2, 4, 8]})"", R""({"minDoc":1024})"", }; @@ -193,14 +177,14 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest005, TestSize.Level0) HWTEST_F(DocumentDBCollectionTest, CollectionTest006, TestSize.Level0) { EXPECT_EQ(GRD_CreateCollection(g_db, "student", R""({"maxDoc":1024})"", 0), GRD_OK); - - EXPECT_EQ(GRD_CreateCollection(g_db, "student", R""({"maxDoc":2048})"", 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_CreateCollection(g_db, "student", R""({"maxDoc":2048})"", 0), GRD_OK); + EXPECT_EQ(GRD_CreateCollection(g_db, "student", R""({"maxDoc":2048})"", CHK_EXIST_COLLECTION), GRD_DATA_CONFLICT); EXPECT_EQ(GRD_DropCollection(g_db, "student", 0), GRD_OK); EXPECT_EQ(GRD_DropCollection(g_db, "student", 0), GRD_OK); - EXPECT_EQ(GRD_DropCollection(g_db, "student", CHK_NON_EXIST_COLLECTION), GRD_NO_DATA); + EXPECT_EQ(GRD_DropCollection(g_db, "student", CHK_NON_EXIST_COLLECTION), GRD_INVALID_ARGS); - // Create collection with different option returnh OK after drop collection + // Create collection with different option return OK after drop collection EXPECT_EQ(GRD_CreateCollection(g_db, "student", R""({"maxDoc":2048})"", 0), GRD_OK); } @@ -213,8 +197,9 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest006, TestSize.Level0) */ HWTEST_F(DocumentDBCollectionTest, CollectionTest007, TestSize.Level0) { - for (int flag : std::vector {2, 4, 8, 1024, UINT32_MAX}) { + for (int flag : std::vector { 2, 4, 8, 1024, UINT32_MAX }) { EXPECT_EQ(GRD_CreateCollection(g_db, "student", "", flag), GRD_INVALID_ARGS); EXPECT_EQ(GRD_DropCollection(g_db, "student", flag), GRD_INVALID_ARGS); } -} \ No newline at end of file +} +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..129ea35b067d8ea17146f0a062d3ffd235368400 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp @@ -0,0 +1,374 @@ +/* +* 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 "cJSON.h" +#include "doc_errno.h" +#include "documentdb_test_utils.h" +#include "grd_base/grd_db_api.h" +#include "grd_base/grd_error.h" +#include "grd_document/grd_document_api.h" +#include "log_print.h" +#include "sqlite_utils.h" + +using namespace DocumentDB; +using namespace testing::ext; +using namespace DocumentDBUnitTest; + +namespace { +std::string g_path = "./document.db"; +GRD_DB *g_db = nullptr; +const char *g_coll = "student"; +constexpr int JSON_LENS_MAX = 1024 * 1024; +class DocumentDBDataTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DocumentDBDataTest::SetUpTestCase(void) {} + +void DocumentDBDataTest::TearDownTestCase(void) {} + +void DocumentDBDataTest::SetUp(void) +{ + EXPECT_EQ(GRD_DBOpen(g_path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &g_db), GRD_OK); + EXPECT_NE(g_db, nullptr); + GRD_DropCollection(g_db, g_coll, 0); + EXPECT_EQ(GRD_CreateCollection(g_db, g_coll, "", 0), GRD_OK); +} + +void DocumentDBDataTest::TearDown(void) +{ + if (g_db != nullptr) { + EXPECT_EQ(GRD_DBClose(g_db, GRD_DB_CLOSE), GRD_OK); + g_db = nullptr; + } + DocumentDBTestUtils::RemoveTestDbFiles(g_path); +} + +/** + * @tc.name: UpsertDataTest001 + * @tc.desc: Test upsert data into collection + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest001, TestSize.Level0) +{ + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, R""({"_id":"1234"})"", document.c_str(), GRD_DOC_REPLACE), 1); + + std::string update = R""({"CC":"AAAA"})""; + EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, R""({"_id":"1234"})"", update.c_str(), 0), 1); + + std::string append = R""({"addr.city":"DDDD"})""; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, R""({"_id":"1234"})"", append.c_str(), GRD_DOC_APPEND), 1); +} + +/** + * @tc.name: UpsertDataTest002 + * @tc.desc: Test upsert data with db is nullptr + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest002, TestSize.Level0) +{ + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + EXPECT_EQ(GRD_UpsertDoc(nullptr, g_coll, "1234", document.c_str(), GRD_DOC_REPLACE), GRD_INVALID_ARGS); +} + +/** + * @tc.name: UpsertDataTest003 + * @tc.desc: Test upsert data with invalid collection name + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest003, TestSize.Level0) +{ + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + std::vector> invalidName = { + { nullptr, GRD_INVALID_ARGS }, + { "", GRD_INVALID_ARGS }, + { "GRD_123", GRD_INVALID_FORMAT }, + { "grd_123", GRD_INVALID_FORMAT }, + { "GM_SYS_123", GRD_INVALID_FORMAT }, + { "gm_sys_123", GRD_INVALID_FORMAT }, + }; + for (auto it : invalidName) { + GLOGD("UpsertDataTest003: upsert data with collectionname: %s", it.first); + EXPECT_EQ(GRD_UpsertDoc(g_db, it.first, "1234", document.c_str(), GRD_DOC_REPLACE), it.second); + } +} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest004, TestSize.Level0) {} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest005, TestSize.Level0) {} + +/** + * @tc.name: UpsertDataTest006 + * @tc.desc: Test upsert data with invalid flags + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest006, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + for (auto flags : std::vector { 2, 4, 8, 64, 1024, UINT32_MAX }) { + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), flags), GRD_INVALID_ARGS); + } +} + +/** + * @tc.name: UpsertDataTest007 + * @tc.desc: Test upsert data with collection not create + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest007, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string val = R""({"name":"Tmono", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; + EXPECT_EQ(GRD_UpsertDoc(g_db, "collection_not_exists", filter.c_str(), val.c_str(), GRD_DOC_REPLACE), + GRD_INVALID_ARGS); +} + +/** + * @tc.name: UpsertDataTest008 + * @tc.desc: Test upsert data with different document in append + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest008, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"name":"Tmn", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_REPLACE), 1); + + std::string updateDoc = R""({"name":"Xue", "case":2, "age":28, "addr":{"city":"shenzhen", "postal":518000}})""; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), updateDoc.c_str(), GRD_DOC_APPEND), 1); +} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest009, TestSize.Level0) +{ + std::string filter = R""({"_id":"abcde"})""; + std::string head = R"({"field1": ")"; + std::string document = + head + string(JSON_LENS_MAX - filter.size() - head.size() - 1, 'a') + "\"}"; // 13 is {"field1": size + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_APPEND), 1); + std::string document2 = head + string(JSON_LENS_MAX - filter.size() - head.size(), 'a') + "\"}"; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document2.c_str(), GRD_DOC_REPLACE), GRD_OVER_LIMIT); +} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest010, TestSize.Level0) +{ + int result = GRD_UpsertDoc(g_db, g_coll, R"({"_id" : "abcde"})", R"({"a00001": {"A":1, "A":2}})", 0); + ASSERT_EQ(result, GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBDataTest, UpsertDataTest011, TestSize.Level0) +{ + int result = + GRD_UpsertDoc(g_db, g_coll, R"({"_id" : "abcde"})", R"({"t1":{"t22":[1,{"t23":1, "t23":1},3 ,4]}})", 0); + ASSERT_EQ(result, GRD_INVALID_FORMAT); +} + +/** + * @tc.name: UpdateDataTest012 + * @tc.desc: Input parameter collectionName is null, invoke the GRD_UpsertDoc interface to update data. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest012, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert a document. + * @tc.expected: step1. return GRD_OK. + */ + int result = GRD_InsertDoc(g_db, g_coll, "{}", 0); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps: step2. Parameter collectionName is Invalid format + * @tc.expected: step2. return Update faild. + */ + result = GRD_UpsertDoc(g_db, "null", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + result = GRD_UpsertDoc(g_db, "!! &%$^%$&*%^。m中文、、请问E:112423123", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); +} + +/** + * @tc.name: UpdateDataTest001 + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpdateDataTest001, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string updateDoc = R""({"name":"Xue"})""; + EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), updateDoc.c_str(), 0), GRD_OK); +} + +/** + * @tc.name: UpdateDataTest002 + * @tc.desc: Test update data with db is nullptr + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpdateDataTest002, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + EXPECT_EQ(GRD_UpdateDoc(nullptr, g_coll, filter.c_str(), document.c_str(), 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: UpdateDataTest003 + * @tc.desc: Test update data with invalid collection name + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DocumentDBDataTest, UpdateDataTest003, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + std::vector> invalidName = { + { nullptr, GRD_INVALID_ARGS }, + { "", GRD_INVALID_ARGS }, + { "GRD_123", GRD_INVALID_FORMAT }, + { "grd_123", GRD_INVALID_FORMAT }, + { "GM_SYS_123", GRD_INVALID_FORMAT }, + { "gm_sys_123", GRD_INVALID_FORMAT }, + }; + for (auto it : invalidName) { + GLOGD("UpdateDataTest003: update data with collectionname: %s", it.first); + EXPECT_EQ(GRD_UpdateDoc(g_db, it.first, filter.c_str(), document.c_str(), 0), it.second); + } +} + +/** + * @tc.name: UpdateDataTest006 + * @tc.desc: Test update data with invalid flag + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDataTest, UpdateDataTest006, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"name":"Tmono", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; + std::vector invalidFlags = { 2, 4, 8, 1024, UINT32_MAX }; + for (auto flag : invalidFlags) { + GLOGD("UpdateDataTest006: update data with flag: %u", flag); + EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), document.c_str(), flag), GRD_INVALID_ARGS); + } +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest007, TestSize.Level0) +{ + int result = GRD_OK; + string doc = R"({"_id":"007", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2":2})"; + result = GRD_InsertDoc(g_db, g_coll, doc.c_str(), 0); + EXPECT_EQ(result, GRD_OK); + result = GRD_UpdateDoc(g_db, g_coll, "{\"field2\" : 2}", "{\"\":3}", 0); + EXPECT_EQ(result, GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest008, TestSize.Level0) +{ + const char *updateStr = + R""({"field2":{"c_field":{"cc_field":{"ccc_field":{"ccc_field":[1, false, 1.234e2, ["hello world!"]]}}}}})""; + int result = GRD_UpdateDoc(g_db, g_coll, "{\"field\" : 2}", updateStr, 0); + int result2 = GRD_UpsertDoc(g_db, g_coll, "{\"field\" : 2}", updateStr, 0); + EXPECT_EQ(result, GRD_INVALID_ARGS); + EXPECT_EQ(result2, GRD_INVALID_ARGS); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest009, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string document = R""({"_id":"1234","field1":{"c_field":{"cc_field":{"ccc_field":1}}},"field2":2})""; + + EXPECT_EQ(GRD_InsertDoc(g_db, g_coll, document.c_str(), 0), GRD_OK); + + std::string updata = R""({"field1":1,"FIELD1":[1,true,1.23456789,"hello world!",null]})""; + EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), updata.c_str(), 0), 1); + + GRD_ResultSet *resultSet = nullptr; + const char *projection = "{}"; + Query query = { filter.c_str(), projection }; + EXPECT_EQ(GRD_FindDoc(g_db, g_coll, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + string valueStr = value; + string repectStr = R""({"_id":"1234","field1":1,"field2":2,"FIELD1":[1,true,1.23456789,"hello world!",null]})""; + EXPECT_EQ((valueStr == repectStr), 1); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest010, TestSize.Level0) +{ + std::string filter = R""({"_id":"1234"})""; + std::string updata = R""({"field1":1, "FIELD1":[1, true, 1.23456789, "hello world!", null]})""; + EXPECT_EQ(GRD_UpdateDoc(g_db, "grd_aa", filter.c_str(), updata.c_str(), 0), GRD_INVALID_FORMAT); + EXPECT_EQ(GRD_UpdateDoc(g_db, "gRd_aa", filter.c_str(), updata.c_str(), 0), GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest011, TestSize.Level3) +{ + int result = GRD_OK; + const char *doc = R"({"_id":"007", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2":2})"; + result = GRD_InsertDoc(g_db, g_coll, doc, 0); + cJSON *updata = cJSON_CreateObject(); + for (int i = 0; i <= 40000; i++) { + string temp = "f" + string(5 - std::to_string(i).size(), '0') + std::to_string(i); + cJSON_AddStringToObject(updata, temp.c_str(), "a"); + } + char *updateStr = cJSON_PrintUnformatted(updata); + result = GRD_UpdateDoc(g_db, g_coll, R""({"_id":"007"})"", updateStr, 0); + EXPECT_EQ(result, 1); + cJSON_Delete(updata); + cJSON_free(updateStr); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest013, TestSize.Level0) +{ + int result = GRD_UpdateDoc(g_db, "GM_Sys", R""({})"", R""({})"", 0); + EXPECT_EQ(result, GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest014, TestSize.Level0) +{ + int result = GRD_UpdateDoc(g_db, g_coll, R""({"abc.":1})"", R""({})"", 0); + EXPECT_EQ(result, GRD_INVALID_ARGS); +} +} // namespace diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8165c73b2d17300929e07ee105f245950929671d --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp @@ -0,0 +1,375 @@ +/* +* 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 "documentdb_test_utils.h" +#include "grd_base/grd_db_api.h" +#include "grd_base/grd_error.h" +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" +#include "grd_document/grd_document_api.h" +#include "grd_resultset_inner.h" +#include "grd_type_inner.h" + +using namespace testing::ext; +using namespace DocumentDBUnitTest; +namespace { +constexpr const char *COLLECTION_NAME = "student"; +constexpr const char *NULL_JSON_STR = "{}"; +const int MAX_COLLECTION_LENS = 511; +std::string g_path = "./document.db"; +GRD_DB *g_db = nullptr; + +class DocumentDBDeleteTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + void InsertDoc(const char *collectionName, const char *document); +}; +void DocumentDBDeleteTest::SetUpTestCase(void) +{ + int status = GRD_DBOpen(g_path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &g_db); + EXPECT_EQ(status, GRD_OK); +} + +void DocumentDBDeleteTest::TearDownTestCase(void) +{ + EXPECT_EQ(GRD_DBClose(g_db, 0), GRD_OK); + DocumentDBTestUtils::RemoveTestDbFiles(g_path); +} + +void DocumentDBDeleteTest::SetUp(void) +{ + /** + * @tc.steps:step1. Create Collection + * @tc.expected: step1. GRD_OK + */ + EXPECT_EQ(GRD_CreateCollection(g_db, "student", "", 0), GRD_OK); + /** + * @tc.steps:step2. Insert many document in order to delete + * @tc.expected: step2. GRD_OK + */ + const char *document1 = "{ \ + \"_id\" : \"1\", \ + \"name\": \"xiaoming\", \ + \"address\": \"beijing\", \ + \"age\" : 15, \ + \"friend\" : {\"name\" : \"David\", \"sex\" : \"female\", \"age\" : 90}, \ + \"subject\": [\"math\", \"English\", \"music\", {\"info\" : \"exam\"}] \ + }"; + const char *document2 = "{ \ + \"_id\" : \"2\", \ + \"name\": \"ori\", \ + \"address\": \"beijing\", \ + \"age\" : 15, \ + \"friend\" : {\"name\" : \"David\", \"sex\" : \"female\", \"age\" : 90}, \ + \"subject\": [\"math\", \"English\", \"music\"] \ + }"; + const char *document3 = "{ \ + \"_id\" : \"3\", \ + \"name\": \"David\", \ + \"address\": \"beijing\", \ + \"age\" : 15, \ + \"friend\" : {\"name\" : \"David\", \"sex\" : \"female\", \"age\" : 90}, \ + \"subject\": [\"Sing\", \"Jump\", \"Rap\", \"BasketBall\"] \ + }"; + DocumentDBDeleteTest::InsertDoc(COLLECTION_NAME, document1); + DocumentDBDeleteTest::InsertDoc(COLLECTION_NAME, document2); + DocumentDBDeleteTest::InsertDoc(COLLECTION_NAME, document3); +} + +void DocumentDBDeleteTest::TearDown(void) +{ + /** + * @tc.steps:step1. Call GRD_DropCollection to drop the collection + * @tc.expected: step1. GRD_OK + */ + EXPECT_EQ(GRD_DropCollection(g_db, COLLECTION_NAME, 0), GRD_OK); +} + +static void ChkDeleteResWithFilter(const char *filter) +{ + /** + * @tc.steps:step1. Try to find the deleted document + * @tc.expected: step1. GRD_OK + */ + Query query; + query.filter = filter; + const char *projection = "{}"; + query.projection = projection; + GRD_ResultSet *resultSet = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + /** + * @tc.steps:step2. The resultset should be NULL + * @tc.expected: step2. GRD_OK + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +void DocumentDBDeleteTest::InsertDoc(const char *collectionName, const char *document) +{ + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName, document, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDelete001 + * @tc.desc: Delete with NULL filter + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest001, TestSize.Level1) +{ + /** + * @tc.steps:step1. Delete all the document + * @tc.expected: step1. GRD_INVALID_ARGS + */ + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, NULL_JSON_STR, 0), 1); +} + +/** + * @tc.name: DocumentDelete002 + * @tc.desc: Delete with filter which has no _id + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest002, TestSize.Level1) +{ + /** + * @tc.steps:step1. Delete with filter which has no _id + * @tc.expected: step1. GRD_INVALID_ARGS + */ + const char *filter = "{\"age\" : 15}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); +} + +/** + * @tc.name: DocumentDelete003 + * @tc.desc: Delete with filter which has more than one fields. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest003, TestSize.Level1) +{ + /** + * @tc.steps:step1. Delete with filter which has more than one fields. + * @tc.expected: step1. GRD_INVALID_ARGS + */ + const char *filter = "{\"_id\" : \"1\", \"age\" : 15}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); +} + +/** + * @tc.name: DocumentDelete004 + * @tc.desc: Test delete with invalid input + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest004, TestSize.Level1) +{ + /** + * @tc.steps:step1. Test delete with un-zero flags + * @tc.expected: step1. GRD_INVALID_ARGS + */ + const char *filter1 = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter1, 1), GRD_INVALID_ARGS); + /** + * @tc.steps:step2. Test delete with NULL collection name + * @tc.expected: step2. GRD_INVALID_ARGS + */ + const char *filter2 = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, NULL, filter2, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step3. Test delete with empty collection name + * @tc.expected: step3. GRD_INVALID_ARGS + */ + const char *filter3 = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, "", filter3, 1), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDelete005 + * @tc.desc: Test delete with same collection name + * but one is uppercase(delete) and the other is lowercase(insert) + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest005, TestSize.Level1) +{ + /** + * @tc.step1: Test delete with same collection name + * but one is uppercase(delete) and the other is lowercase(insert) + * @tc.expected: step1. GRD_INVALID_ARGS + */ + const char *filter = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); + /** + * @tc.step2: Check whether doc has been deleted compeletely + * @tc.expected: step2. GRD_OK + */ + ChkDeleteResWithFilter(filter); +} + +/** + * @tc.name: DocumentDelete006 + * @tc.desc: Test delete after calling find interface + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest006, TestSize.Level1) +{ + /** + * @tc.step1: Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. GRD_OK + */ + const char *filter = "{\"_id\" : \"1\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); + /** + * @tc.step2: Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDelete007 + * @tc.desc: Test delete with too long collectionName. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest007, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"1\"}"; + string collectionName1(MAX_COLLECTION_LENS, 'a'); + EXPECT_EQ(GRD_CreateCollection(g_db, collectionName1.c_str(), "", 0), GRD_OK); + EXPECT_EQ(GRD_DeleteDoc(g_db, collectionName1.c_str(), filter, 0), 0); + EXPECT_EQ(GRD_DropCollection(g_db, collectionName1.c_str(), 0), GRD_OK); + + string collectionName2(MAX_COLLECTION_LENS + 1, 'a'); + EXPECT_EQ(GRD_DeleteDoc(g_db, collectionName2.c_str(), filter, 0), GRD_OVER_LIMIT); +} + +/** + * @tc.name: DocumentDelete008 + * @tc.desc: Test delete with invalid NULL input for all parameters. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest008, TestSize.Level1) +{ + /** + * @tc.steps:step1. Delete with filter which has more than one fields. + * @tc.expected: step1. GRD_INVALID_ARGS + */ + const char *filter = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(NULL, COLLECTION_NAME, filter, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, NULL, filter, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, "", filter, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, NULL, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, "", 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, "notExisted", filter, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDelete010 + * @tc.desc: Test delete document when filter _id is int and string + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest010, TestSize.Level1) +{ + /** + * @tc.steps:step1. Test delete document when filter _id is int and string. + * @tc.expected: step1. GRD_INVALID_ARGS + */ + std::vector filterVec = { R"({"_id" : 1})", R"({"_id":[1, 2]})", R"({"_id" : {"t1" : 1}})", + R"({"_id":null})", R"({"_id":true})", R"({"_id" : 1.333})", R"({"_id" : -2.0})" }; + for (const auto &item : filterVec) { + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, item.c_str(), 0), GRD_INVALID_ARGS); + } + const char *filter = "{\"_id\" : \"1\"}"; + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); +} + +/** + * @tc.name: DocumentDelete011 + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest011, TestSize.Level1) +{ + /** + * @tc.step1: Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. GRD_OK + */ + const char *filter = "{\"_id\" : \"1\"}"; + const char *filter2 = "{\"subject.info\" : \"exam\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter2, 0), 1); + /** + * @tc.step2: Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDelete012 + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDeleteTest, DeleteDBTest012, TestSize.Level1) +{ + /** + * @tc.step1: Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. GRD_OK + */ + const char *filter = "{\"_id\" : \"1\"}"; + const char *filter2 = "{\"subject.info\" : \"exam\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter2, 0), 1); + /** + * @tc.step2: Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..654294a3c924d00700f184eecbb24f1bb28b27e5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp @@ -0,0 +1,1505 @@ +/* +* 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 +#include + +#include "doc_errno.h" +#include "documentdb_test_utils.h" +#include "grd_base/grd_db_api.h" +#include "grd_base/grd_error.h" +#include "grd_base/grd_resultset_api.h" +#include "grd_base/grd_type_export.h" +#include "grd_document/grd_document_api.h" +#include "grd_resultset_inner.h" +#include "grd_type_inner.h" +#include "log_print.h" + +using namespace testing::ext; +using namespace DocumentDBUnitTest; + +namespace { +std::string g_path = "./document.db"; +GRD_DB *g_db = nullptr; +constexpr const char *COLLECTION_NAME = "student"; +constexpr const char *colName = "data_"; +const int MAX_COLLECTION_NAME = 511; + +const int MAX_ID_LENS = 899; +static const char *g_document1 = "{\"_id\" : \"1\", \"name\":\"doc1\",\"item\":\"journal\",\"personInfo\":\ + {\"school\":\"AB\", \"age\" : 51}}"; +static const char *g_document2 = "{\"_id\" : \"2\", \"name\":\"doc2\",\"item\": 1, \"personInfo\":\ + [1, \"my string\", {\"school\":\"AB\", \"age\" : 51}, true, {\"school\":\"CD\", \"age\" : 15}, false]}"; +static const char *g_document3 = "{\"_id\" : \"3\", \"name\":\"doc3\",\"item\":\"notebook\",\"personInfo\":\ + [{\"school\":\"C\", \"age\" : 5}]}"; +static const char *g_document4 = "{\"_id\" : \"4\", \"name\":\"doc4\",\"item\":\"paper\",\"personInfo\":\ + {\"grade\" : 1, \"school\":\"A\", \"age\" : 18}}"; +static const char *g_document5 = "{\"_id\" : \"5\", \"name\":\"doc5\",\"item\":\"journal\",\"personInfo\":\ + [{\"sex\" : \"woma\", \"school\" : \"B\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 35}]}"; +static const char *g_document6 = "{\"_id\" : \"6\", \"name\":\"doc6\",\"item\":false,\"personInfo\":\ + [{\"school\":\"B\", \"teacher\" : \"mike\", \"age\" : 15},\ + {\"school\":\"C\", \"teacher\" : \"moon\", \"age\" : 20}]}"; + +static const char *g_document7 = "{\"_id\" : \"7\", \"name\":\"doc7\",\"item\":\"fruit\",\"other_Info\":\ + [{\"school\":\"BX\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 35}]}"; +static const char *g_document8 = "{\"_id\" : \"8\", \"name\":\"doc8\",\"item\":true,\"personInfo\":\ + [{\"school\":\"B\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 35}]}"; +static const char *g_document9 = "{\"_id\" : \"9\", \"name\":\"doc9\",\"item\": true}"; +static const char *g_document10 = "{\"_id\" : \"10\", \"name\":\"doc10\", \"parent\" : \"kate\"}"; +static const char *g_document11 = "{\"_id\" : \"11\", \"name\":\"doc11\", \"other\" : \"null\"}"; +static const char *g_document12 = "{\"_id\" : \"12\", \"name\":\"doc12\",\"other\" : null}"; +static const char *g_document13 = "{\"_id\" : \"13\", \"name\":\"doc13\",\"item\" : \"shoes\",\"personInfo\":\ + {\"school\":\"AB\", \"age\" : 15}}"; +static const char *g_document14 = "{\"_id\" : \"14\", \"name\":\"doc14\",\"item\" : true,\"personInfo\":\ + [{\"school\":\"B\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 85}]}"; +static const char *g_document15 = "{\"_id\" : \"15\", \"name\":\"doc15\",\"personInfo\":[{\"school\":\"C\", \"age\" : " + "5}]}"; +static const char *g_document16 = "{\"_id\" : \"16\", \"name\":\"doc16\", \"nested1\":{\"nested2\":{\"nested3\":\ + {\"nested4\":\"ABC\", \"field2\":\"CCC\"}}}}"; +static const char *g_document17 = "{\"_id\" : \"17\", \"name\":\"doc17\",\"personInfo\":\"oh,ok\"}"; +static const char *g_document18 = "{\"_id\" : \"18\", \"name\":\"doc18\",\"item\" : \"mobile phone\",\"personInfo\":\ + {\"school\":\"DD\", \"age\":66}, \"color\":\"blue\"}"; +static const char *g_document19 = "{\"_id\" : \"19\", \"name\":\"doc19\",\"ITEM\" : true,\"PERSONINFO\":\ + {\"school\":\"AB\", \"age\":15}}"; +static const char *g_document20 = "{\"_id\" : \"20\", \"name\":\"doc20\",\"ITEM\" : true,\"personInfo\":\ + [{\"SCHOOL\":\"B\", \"AGE\":15}, {\"SCHOOL\":\"C\", \"AGE\":35}]}"; +static const char *g_document23 = "{\"_id\" : \"23\", \"name\":\"doc22\",\"ITEM\" : " + "true,\"personInfo\":[{\"school\":\"b\", \"age\":15}, [{\"school\":\"doc23\"}, 10, " + "{\"school\":\"doc23\"}, true, {\"school\":\"y\"}], {\"school\":\"b\"}]}"; +static std::vector g_data = { g_document1, g_document2, g_document3, g_document4, g_document5, + g_document6, g_document7, g_document8, g_document9, g_document10, g_document11, g_document12, g_document13, + g_document14, g_document15, g_document16, g_document17, g_document18, g_document19, g_document20, g_document23 }; + +static void InsertData(GRD_DB *g_db, const char *collectionName) +{ + for (const auto &item : g_data) { + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName, item, 0), GRD_OK); + } +} + +static void CompareValue(const char *value, const char *targetValue) +{ + int errCode; + DocumentDB::JsonObject valueObj = DocumentDB::JsonObject::Parse(value, errCode); + EXPECT_EQ(errCode, DocumentDB::E_OK); + DocumentDB::JsonObject targetValueObj = DocumentDB::JsonObject::Parse(targetValue, errCode); + EXPECT_EQ(errCode, DocumentDB::E_OK); + EXPECT_EQ(valueObj.Print(), targetValueObj.Print()); +} + +class DocumentDBFindTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + void InsertDoc(const char *collectionName, const char *document); +}; +void DocumentDBFindTest::SetUpTestCase(void) +{ + int status = GRD_DBOpen(g_path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &g_db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_CreateCollection(g_db, COLLECTION_NAME, "", 0), GRD_OK); + EXPECT_NE(g_db, nullptr); +} + +void DocumentDBFindTest::TearDownTestCase(void) +{ + EXPECT_EQ(GRD_DBClose(g_db, 0), GRD_OK); + DocumentDBTestUtils::RemoveTestDbFiles(g_path); +} + +void DocumentDBFindTest::SetUp(void) +{ + EXPECT_EQ(GRD_DropCollection(g_db, COLLECTION_NAME, 0), GRD_OK); + EXPECT_EQ(GRD_CreateCollection(g_db, COLLECTION_NAME, "", 0), GRD_OK); + InsertData(g_db, "student"); +} + +void DocumentDBFindTest::TearDown(void) {} + +/** + * @tc.name: DocumentDBFindTest001 + * @tc.desc: Test Insert document db + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest001, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"_id\" : \"6\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document6); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest002 + * @tc.desc: Test filter with multiple fields and _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest002, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with multiple and _id. and get the record according to filter condition. + * @tc.expected: step1. Failed to get the record, the result is GRD_INVALID_ARGS, + * GRD_GetValue return GRD_NOT_AVAILABLE and GRD_Next return GRD_NO_DATA. + */ + const char *filter = "{\"_id\" : \"6\", \"name\":\"doc6\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. GRD_GetValue return GRD_INVALID_ARGS and GRD_Next return GRD_INVALID_ARGS. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest004 + * @tc.desc: test filter with string filter without _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest004, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter without _id and get the record according to filter condition. + * @tc.expected: step1. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + const char *filter = "{\"name\":\"doc6\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. GRD_GetValue return GRD_INVALID_ARGS and GRD_Next return GRD_INVALID_ARGS. + */ + char *value = nullptr; + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest006 + * @tc.desc: test filter field with id which has different type of value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest006, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id which value is string + * @tc.expected: step1. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet1 = nullptr; + const char *filter1 = "{\"_id\" : \"valstring\"}"; + Query query1 = { filter1, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query1, 1, &resultSet1), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet1), GRD_OK); + + /** + * @tc.steps: step2. Create filter with _id which value is number + * @tc.expected: step2. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet2 = nullptr; + const char *filter2 = "{\"_id\" : 1}"; + Query query2 = { filter2, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query2, 1, &resultSet2), GRD_INVALID_ARGS); + + /** + * @tc.steps: step3. Create filter with _id which value is array + * @tc.expected: step3. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet3 = nullptr; + const char *filter3 = "{\"_id\" : [\"2\", 1]}"; + Query query3 = { filter3, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query3, 1, &resultSet3), GRD_INVALID_ARGS); + + /** + * @tc.steps: step4. Create filter with _id which value is object + * @tc.expected: step4. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet4 = nullptr; + const char *filter4 = "{\"_id\" : {\"info_val\" : \"1\"}}"; + Query query4 = { filter4, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query4, 1, &resultSet4), GRD_INVALID_ARGS); + + /** + * @tc.steps: step5. Create filter with _id which value is bool + * @tc.expected: step5. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet5 = nullptr; + const char *filter5 = "{\"_id\" : true}"; + Query query5 = { filter5, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query5, 1, &resultSet5), GRD_INVALID_ARGS); + + /** + * @tc.steps: step6. Create filter with _id which value is null + * @tc.expected: step6. Failed to get the record, the result is GRD_INVALID_ARGS, + */ + GRD_ResultSet *resultSet6 = nullptr; + const char *filter6 = "{\"_id\" : null}"; + Query query6 = { filter6, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query6, 1, &resultSet6), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest016 + * @tc.desc: Test filter with collection Name is invalid. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest016, TestSize.Level1) +{ + const char *colName1 = "grd_type"; + const char *colName2 = "GM_SYS_sysfff"; + GRD_ResultSet *resultSet = nullptr; + const char *filter = "{\"_id\" : \"1\"}"; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, colName1, query, 1, &resultSet), GRD_INVALID_FORMAT); + EXPECT_EQ(GRD_FindDoc(g_db, colName2, query, 1, &resultSet), GRD_INVALID_FORMAT); +} + +/** + * @tc.name: DocumentDBFindTest019 + * @tc.desc: Test filter field with no result + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest019, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"100\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest023 + * @tc.desc: Test filter field with double find. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest023, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"_id\" : \"6\"}"; + GRD_ResultSet *resultSet = nullptr; + GRD_ResultSet *resultSet2 = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet2), GRD_RESOURCE_BUSY); + + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document6); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document6); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest024 + * @tc.desc: Test filter field with multi collections + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest024, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"6\"}"; + GRD_ResultSet *resultSet = nullptr; + GRD_ResultSet *resultSet2 = nullptr; + Query query = { filter, "{}" }; + const char *collectionName = "DocumentDBFindTest024"; + EXPECT_EQ(GRD_CreateCollection(g_db, collectionName, "", 0), GRD_OK); + InsertData(g_db, collectionName); + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_FindDoc(g_db, collectionName, query, 1, &resultSet2), GRD_OK); + + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document6); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + + EXPECT_EQ(GRD_Next(resultSet2), GRD_OK); + char *value2 = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet2, &value2), GRD_OK); + CompareValue(value2, g_document6); + EXPECT_EQ(GRD_FreeValue(value2), GRD_OK); + + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_Next(resultSet2), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_GetValue(resultSet2, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet2), GRD_OK); + + EXPECT_EQ(GRD_DropCollection(g_db, collectionName, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest025 + * @tc.desc: Test nested projection, with viewType equals to 1. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest025, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document16, _id flag is 0. + * Create projection to display name,nested4. + * @tc.expected: step1. resultSet init successfuly, the result is GRD_OK, + */ + const char *filter = "{\"_id\" : \"16\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\": true, \"nested1.nested2.nested3.nested4\":true}"; + const char *targetDocument = "{\"name\":\"doc16\", \"nested1\":{\"nested2\":{\"nested3\":\ + {\"nested4\":\"ABC\"}}}}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. After loop, cannot get more record. + * @tc.expected: step2. Return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step3. Create filter to match g_document16, _id flag is 0; + * Create projection to display name、nested4 with different projection format. + * @tc.expected: step3. succeed to get the record. + */ + projectionInfo = "{\"name\": true, \"nested1\":{\"nested2\":{\"nested3\":{\"nested4\":true}}}}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step4. After loop, cannot get more record. + * @tc.expected: step4. return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step5. Create filter to match g_document16, _id flag is 0. + * Create projection to conceal name,nested4 with different projection format. + * @tc.expected: step5. succeed to get the record. + */ + projectionInfo = "{\"name\": 0, \"nested1.nested2.nested3.nested4\":0}"; + targetDocument = "{\"nested1\":{\"nested2\":{\"nested3\":{\"field2\":\"CCC\"}}}}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest027 + * @tc.desc: Test projection with invalid field, _id field equals to 1. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest027, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, other _info and non existing field. + * @tc.expected: step1. Match the g_document7 and display name, other_info + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\": true, \"other_Info\":true, \"non_exist_field\":true}"; + const char *targetDocument = "{\"name\": \"doc7\", \"other_Info\":[{\"school\":\"BX\", \"age\":15},\ + {\"school\":\"C\", \"age\":35}]}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, other _info and existing field with space. + * @tc.expected: step2. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\": true, \"other_Info\":true, \" item \":true}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step3. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, other _info and existing field with different case. + * @tc.expected: step3. Match the g_document7 and display name, other_Info. + */ + projectionInfo = "{\"name\": true, \"other_Info\":true, \"ITEM\": true}"; + query = { filter, projectionInfo }; + resultSet = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest028 + * @tc.desc: Test projection with invalid field in Array,_id field equals to 1. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest028, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, non existing field in array. + * @tc.expected: step1. Match the g_document7 and display name, other_info. + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\": true, \"other_Info.non_exist_field\":true}"; + const char *targetDocument = "{\"name\": \"doc7\"}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, other _info and existing field with space. + * @tc.expected: step2. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\": true, \"other_Info\":{\"non_exist_field\":true}}"; + query = { filter, projectionInfo }; + resultSet = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step3. Create filter to match g_document7, _id flag is 0. + * Create projection to display name, non existing field in array with index format. + * @tc.expected: step3. Match the g_document7 and display name, other_Info. + */ + projectionInfo = "{\"name\": true, \"other_Info.0\": true}"; + query = { filter, projectionInfo }; + resultSet = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest029 + * @tc.desc: Test projection with path conflict._id field equals to 0. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest029, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document4, _id flag is 0. + * Create projection to display conflict path. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"4\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"personInfo\": true, \"personInfo.grade\": true}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest030 + * @tc.desc: Test _id flag and field.None exist field. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest030, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * @tc.expected: step1. Match the g_document7 and return empty json. + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"non_exist_field\":true}"; + int flag = 0; + const char *targetDocument = "{}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 1. + * @tc.expected: step2. Match g_document7, and return a json with _id. + */ + resultSet = nullptr; + flag = 1; + targetDocument = "{\"_id\": \"7\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest031 + * @tc.desc: Test _id flag and field.Exist field with 1 value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest031, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * @tc.expected: step1. Match the g_document7 and return json with name, item. + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":true, \"item\":true}"; + int flag = 0; + const char *targetDocument = "{\"name\":\"doc7\", \"item\":\"fruit\"}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 1. + * @tc.expected: step2. Match g_document7, and return a json with _id. + */ + resultSet = nullptr; + flag = 1; + projectionInfo = "{\"name\": 1, \"item\": 1}"; + targetDocument = "{\"_id\":\"7\", \"name\":\"doc7\", \"item\":\"fruit\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest032 + * @tc.desc: Test _id flag and field.Exist field with 1 value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest032, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * @tc.expected: step1. Match the g_document7 and return json with name, item. + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":true, \"item\":true}"; + int flag = 0; + const char *targetDocument = "{\"name\":\"doc7\", \"item\":\"fruit\"}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 1. + * @tc.expected: step2. Match g_document7, and return a json with _id. + */ + resultSet = nullptr; + flag = 1; + projectionInfo = "{\"name\": 1, \"item\": 1}"; + targetDocument = "{\"_id\":\"7\", \"name\":\"doc7\", \"item\":\"fruit\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step3. Create filter to match g_document7, _id flag is 1.Projection value is not 0. + * @tc.expected: step3. Match g_document7, and return a json with name, item and _id. + */ + resultSet = nullptr; + flag = 1; + projectionInfo = "{\"name\": 10, \"item\": 10}"; + targetDocument = "{\"_id\":\"7\", \"name\":\"doc7\", \"item\":\"fruit\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest033 + * @tc.desc: Test _id flag and field.Exist field with 0 value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest033, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document7, _id flag is 0. + * @tc.expected: step1. Match the g_document7 and return json with name, item and _id + */ + const char *filter = "{\"_id\" : \"7\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":false, \"item\":false}"; + int flag = 0; + const char *targetDocument = "{\"other_Info\":[{\"school\":\"BX\", \"age\" : 15}, {\"school\":\"C\", \"age\" : " + "35}]}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step2. Create filter to match g_document7, _id flag is 1. + * @tc.expected: step2. Match g_document7, and return a json without name and item. + */ + resultSet = nullptr; + flag = 1; + projectionInfo = "{\"name\": 0, \"item\": 0}"; + targetDocument = "{\"_id\": \"7\", \"other_Info\":[{\"school\":\"BX\", \"age\" : 15}, {\"school\":\"C\", \"age\" " + ": 35}]}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest034 + * @tc.desc: Test projection with nonexist field in nested structure. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest034, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter to match g_document4, _id flag is 0. + * @tc.expected: step1. Match the g_document4 and return json without name + */ + const char *filter = "{\"_id\" : \"4\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\": 1, \"personInfo.grade1\": 1, \ + \"personInfo.shool1\": 1, \"personInfo.age1\": 1}"; + int flag = 0; + const char *targetDocument = "{\"name\":\"doc4\"}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Create filter to match g_document4, _id flag is 0, display part of fields in nested structure. + * @tc.expected: step2. Match the g_document4 and return json without name + */ + projectionInfo = "{\"name\": false, \"personInfo.grade1\": false, \ + \"personInfo.shool1\": false, \"personInfo.age1\": false}"; + const char *targetDocument2 = "{\"item\":\"paper\",\"personInfo\":{\"grade\" : 1, \"school\":\"A\", \"age\" : " + "18}}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument2); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step3. Create filter to match g_document4, _id flag is 0, display part of fields in nested structure. + * @tc.expected: step3. Match the g_document4 and return json with name, personInfo.school and personInfo.age. + */ + projectionInfo = "{\"name\": 1, \"personInfo.school\": 1, \"personInfo.age\": 1}"; + const char *targetDocument3 = "{\"name\":\"doc4\", \"personInfo\": {\"school\":\"A\", \"age\" : 18}}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument3); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step4. Create filter to match g_document4, _id flag is 0, display part of fields in nested structure. + * @tc.expected: step4. Match the g_document4 and return json with name, personInfo.school + */ + projectionInfo = "{\"name\": 1, \"personInfo.school\": 1, \"personInfo.age1\": 1}"; + const char *targetDocument4 = "{\"name\":\"doc4\", \"personInfo\": {\"school\":\"A\"}}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument4); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest035 + * @tc.desc: test filter with id string filter + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest035, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. succeed to get the record, the matching record is g_document17 + */ + const char *filter = "{\"_id\" : \"17\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, GRD_DOC_ID_DISPLAY, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document17); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest036 + * @tc.desc: Test with invalid collectionName. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest036, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with invalid collectionName. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"17\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, "", query, 0, &resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FindDoc(g_db, nullptr, query, 0, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest037 + * @tc.desc: Test field with different value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest037, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test field with different value.some are 1, other are 0. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"4\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":1, \"personInfo\":0, \"item\":1}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step2. Test field with different value.some are 2, other are 0. + * @tc.expected: step2. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":2, \"personInfo\":0, \"item\":2}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step3. Test field with different value.some are 0, other are true. + * @tc.expected: step3. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":true, \"personInfo\":0, \"item\":true}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step4. Test field with different value.some are 0, other are "". + * @tc.expected: step4. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":\"\", \"personInfo\":0, \"item\":\"\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step5. Test field with different value.some are 1, other are false. + * @tc.expected: step5. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":false, \"personInfo\":1, \"item\":false"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_FORMAT); + + /** + * @tc.steps: step6. Test field with different value.some are -1.123, other are false. + * @tc.expected: step6. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":false, \"personInfo\":-1.123, \"item\":false"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_FORMAT); + + /** + * @tc.steps: step7. Test field with different value.some are true, other are false. + * @tc.expected: step7. Return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"name\":false, \"personInfo\":true, \"item\":false"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_FORMAT); +} + +/** + * @tc.name: DocumentDBFindTest038 + * @tc.desc: Test field with false value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest038, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test field with different false value. Some are false, other are 0. flag is 0. + * @tc.expected: step1. Match the g_document6 and return empty json. + */ + const char *filter = "{\"_id\" : \"6\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":false, \"personInfo\": 0, \"item\":0}"; + int flag = 0; + const char *targetDocument = "{}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Test field with different false value.Some are false, others are 0. flag is 1. + * @tc.expected: step2. Match g_document6, Return json with _id. + */ + targetDocument = "{\"_id\": \"6\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest039 + * @tc.desc: Test field with true value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest039, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test field with different true value. Some are true, other are 1. flag is 0. + * @tc.expected: step1. Match the g_document18 and return json with name, item, personInfo.age and color. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"name\":true, \"personInfo.age\": \"\", \"item\":1, \"color\":10, \"nonExist\" : " + "-100}"; + const char *targetDocument = "{\"name\":\"doc18\", \"item\":\"mobile phone\", \"personInfo\":\ + {\"age\":66}, \"color\":\"blue\"}"; + int flag = 0; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + + /** + * @tc.steps: step2. Test field with different true value.Some are false, others are 0. flag is 1. + * @tc.expected: step2. Match g_document18, Return json with name, item, personInfo.age, color and _id. + */ + targetDocument = "{\"_id\" : \"18\", \"name\":\"doc18\",\"item\" : \"mobile phone\",\"personInfo\":\ + {\"age\":66}, \"color\":\"blue\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest040 + * @tc.desc: Test field with invalid value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest040, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test field with invalid value.Value is array. + * @tc.expected: step1. Match the g_document18 and return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"personInfo\":[true, 1]}"; + int flag = 1; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step2. Test field with invalid value.Value is null. + * @tc.expected: step2. Match the g_document18 and return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"personInfo\":null}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step3. Test field with invalid value.Value is invalid string. + * @tc.expected: step3. Match the g_document18 and return GRD_INVALID_ARGS. + */ + projectionInfo = "{\"personInfo\":\"invalid string.\"}"; + query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest042 + * @tc.desc: Test field with no existed uppercase filter + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest042, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test field with no existed uppercase filter. + * @tc.expected: step1. not match any item. + */ + const char *filter = "{\"_iD\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"Name\":true, \"personInfo.age\": \"\", \"item\":1, \"COLOR\":10, \"nonExist\" : " + "-100}"; + int flag = 0; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + /** + * @tc.steps: step2. Test field with upper projection. + * @tc.expected: step2. Match g_document18, Return json with item, personInfo.age, color and _id. + */ + const char *filter1 = "{\"_id\" : \"18\"}"; + const char *targetDocument = "{\"_id\" : \"18\", \"item\" : \"mobile phone\",\"personInfo\":\ + {\"age\":66}}"; + query = { filter1, projectionInfo }; + char *value = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest044 + * @tc.desc: Test field with uppercase projection + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest044, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with false uppercase projection + * @tc.expected: step1. Match g_document18, Return json with item, personInfo.age and _id. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{\"Name\":0, \"personInfo.age\": false, \"personInfo.SCHOOL\": false, \"item\":\ + false, \"COLOR\":false, \"nonExist\" : false}"; + const char *targetDocument = "{\"_id\" : \"18\", \"name\":\"doc18\", \"personInfo\":\ + {\"school\":\"DD\"}, \"color\":\"blue\"}"; + Query query = { filter, projectionInfo }; + char *value = nullptr; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, targetDocument); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest045 + * @tc.desc: Test field with too long collectionName + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest045, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with false uppercase projection + * @tc.expected: step1. Match g_document18, Return json with item, personInfo.age and _id. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + string collectionName1(MAX_COLLECTION_NAME, 'a'); + ASSERT_EQ(GRD_CreateCollection(g_db, collectionName1.c_str(), "", 0), GRD_OK); + EXPECT_EQ(GRD_FindDoc(g_db, collectionName1.c_str(), query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + ASSERT_EQ(GRD_DropCollection(g_db, collectionName1.c_str(), 0), GRD_OK); + + string collectionName2(MAX_COLLECTION_NAME + 1, 'a'); + EXPECT_EQ(GRD_FindDoc(g_db, collectionName2.c_str(), query, 1, &resultSet), GRD_OVER_LIMIT); + EXPECT_EQ(GRD_FindDoc(g_db, "", query, 1, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest052 + * @tc.desc: Test field when id string len is large than max + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest052, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with false uppercase projection + * @tc.expected: step1. Match g_document18, Return json with item, personInfo.age and _id. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + string collectionName1(MAX_COLLECTION_NAME, 'a'); + ASSERT_EQ(GRD_CreateCollection(g_db, collectionName1.c_str(), "", 0), GRD_OK); + EXPECT_EQ(GRD_FindDoc(g_db, collectionName1.c_str(), query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + ASSERT_EQ(GRD_DropCollection(g_db, collectionName1.c_str(), 0), GRD_OK); + + string collectionName2(MAX_COLLECTION_NAME + 1, 'a'); + EXPECT_EQ(GRD_FindDoc(g_db, collectionName2.c_str(), query, 1, &resultSet), GRD_OVER_LIMIT); + EXPECT_EQ(GRD_FindDoc(g_db, "", query, 1, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest053 + * @tc.desc: Test with invalid flags + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest053, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with invalid flags which is 3. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 3, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps:step1.parameter flags is int_max + * @tc.expected:step1.GRD_INVALID_ARGS + */ + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, INT_MAX, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps:step1.parameter flags is INT_MIN + * @tc.expected:step1.GRD_INVALID_ARGS + */ + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, INT_MIN, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest054 + * @tc.desc: Test with null g_db and resultSet, filter. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest054, TestSize.Level1) +{ + /** + * @tc.steps: step1. Test with null g_db. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + const char *filter = "{\"_id\" : \"18\"}"; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{}"; + Query query = { filter, projectionInfo }; + EXPECT_EQ(GRD_FindDoc(nullptr, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + + /** + * @tc.steps: step2. Test with null resultSet. + * @tc.expected: step2. Return GRD_INVALID_ARGS. + */ + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, nullptr), GRD_INVALID_ARGS); + + /** + * @tc.steps: step1. Test with query that has two nullptr data. + * @tc.expected: step1. Return GRD_INVALID_ARGS. + */ + query = { nullptr, nullptr }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBFindTest055 + * @tc.desc: Find doc, but filter' _id value lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest055, TestSize.Level1) +{ + /** + * @tc.steps:step1.Find doc, but filter' _id value lens is larger than MAX_ID_LENS + * @tc.expected:step1.GRD_OVER_LIMIT. + */ + string document1 = "{\"_id\" : "; + string document2 = "\""; + string document4 = "\""; + string document5 = "}"; + string document_midlle(MAX_ID_LENS + 1, 'k'); + string filter = document1 + document2 + document_midlle + document4 + document5; + GRD_ResultSet *resultSet = nullptr; + const char *projectionInfo = "{}"; + Query query = { filter.c_str(), projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OVER_LIMIT); + + /** + * @tc.steps:step1.Find doc, filter' _id value lens is equal as MAX_ID_LENS + * @tc.expected:step1.GRD_OK. + */ + string document_midlle2(MAX_ID_LENS, 'k'); + filter = document1 + document2 + document_midlle2 + document4 + document5; + query = { filter.c_str(), projectionInfo }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest056 + * @tc.desc: Test findDoc with no _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest056, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"personInfo\" : {\"school\":\"B\"}}"; + GRD_ResultSet *resultSet = nullptr; + Query query = { filter, "{}" }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document5); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentDBFindTest056 + * @tc.desc: Test findDoc with no _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest057, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"personInfo\" : {\"school\":\"B\"}}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = "{\"version\": 1}"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} +/** + * @tc.name: DocumentDBFindTest058 + * @tc.desc: Test findDoc with no _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest058, TestSize.Level1) {} + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest059, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"personInfo\" : {\"school\":\"B\"}}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = R"({"a00001":1, "a00001":1})"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_FORMAT); +} + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest060, TestSize.Level1) +{ + const char *filter = "{}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = R"({"abc123_.":1})"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_ARGS); +} + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest061, TestSize.Level1) +{ + const char *document064 = "{\"_id\" : \"64\", \"a\":1, \"doc64\" : 2}"; + const char *document063 = "{\"_id\" : \"63\", \"a\":1, \"doc63\" : 2}"; + const char *document062 = "{\"_id\" : \"62\", \"a\":1, \"doc62\" : 2}"; + const char *document061 = "{\"_id\" : \"61\", \"a\":1, \"doc61\" : 2}"; + EXPECT_EQ(GRD_InsertDoc(g_db, COLLECTION_NAME, document064, 0), GRD_OK); + EXPECT_EQ(GRD_InsertDoc(g_db, COLLECTION_NAME, document063, 0), GRD_OK); + EXPECT_EQ(GRD_InsertDoc(g_db, COLLECTION_NAME, document062, 0), GRD_OK); + EXPECT_EQ(GRD_InsertDoc(g_db, COLLECTION_NAME, document061, 0), GRD_OK); + const char *filter = "{\"a\":1}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = R"({})"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = nullptr; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, document061); + + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, document062); + + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, document063); + + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, document064); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest062, TestSize.Level1) +{ + const char *filter = R"({"abc123_.":1})"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = R"({"abc123_":1})"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_ARGS); +} + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest063, TestSize.Level1) +{ + GRD_DB *test_db = nullptr; + std::string path = "./dataShare.db"; + int status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &test_db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_CreateCollection(test_db, colName, "", 0), GRD_OK); + string document1 = "{\"_id\":\"key2_11_com.acts.ohos.data.datasharetestclient_100\",\ + \"bundleName\":\"com.acts.ohos.data.datasharetestclient\",\"key\":\"key2\",\ + \"subscriberId\":11,\"timestamp\":1509100700,""\"userId\":100,\"value\":{\"type\":0,"; + string document2 = "\"value\":["; + string document3 = "5,"; + string document4 = document3; + for (int i = 0; i < 100000; i++) { + document4 += document3; + } + document4.push_back('5'); + string document5 = "]}}"; + string document0635 = document1 + document2 + document4 + document5; + EXPECT_EQ(GRD_InsertDoc(test_db, colName, document0635.c_str(), 0), GRD_OK); + EXPECT_EQ(status, GRD_OK); + const char *filter = "{}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = "{\"id_\":true, \"timestamp\":true, \"key\":true, \"bundleName\": true, " + "\"subscriberId\": true}"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(test_db, colName, query, 1, &resultSet), GRD_OK); + char *value; + while (GRD_Next(resultSet) == GRD_OK) { + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + GRD_FreeValue(value); + } + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + EXPECT_EQ(GRD_DBClose(test_db, 0), GRD_OK); + DocumentDBTestUtils::RemoveTestDbFiles(path.c_str()); +} +} // namespace diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e862bb6f03454940e39a9bdc2d711020c5d8c2b --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp @@ -0,0 +1,835 @@ +/* +* 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 + +#include "documentdb_test_utils.h" +#include "grd_base/grd_db_api.h" +#include "grd_base/grd_error.h" +#include "grd_document/grd_document_api.h" + +using namespace testing::ext; +using namespace DocumentDBUnitTest; + +namespace { +std::string g_path = "./document.db"; +GRD_DB *g_db = nullptr; +const char *RIGHT_COLLECTION_NAME = "student"; +const char *NO_EXIST_COLLECTION_NAME = "no_exisit"; +const int MAX_COLLECTION_LENS = 511; +const int MAX_ID_LENS = 899; + +static void TestInsertDocIntoCertainColl(const char *collectionName, const char *projection, int expectedResult) +{ + /** + * @tc.steps: step1. Create Collection + * @tc.expected: step1. GRD_OK + */ + EXPECT_EQ(GRD_CreateCollection(g_db, collectionName, "", 0), expectedResult); + /** + * @tc.steps: step2. Insert projection into colloction. + * @tc.expected: step2. GRD_OK + */ + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName, projection, 0), expectedResult); + /** + * @tc.steps: step3. Call GRD_DroCollection to drop the collection. + * @tc.expected: step3. GRD_OK + */ + EXPECT_EQ(GRD_DropCollection(g_db, collectionName, 0), expectedResult); +} + +class DocumentDBInsertTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DocumentDBInsertTest::SetUpTestCase(void) +{ + int status = GRD_DBOpen(g_path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &g_db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_CreateCollection(g_db, "student", "", 0), GRD_OK); + EXPECT_NE(g_db, nullptr); +} + +void DocumentDBInsertTest::TearDownTestCase(void) +{ + EXPECT_EQ(GRD_DBClose(g_db, 0), GRD_OK); + DocumentDBTestUtils::RemoveTestDbFiles(g_path); +} + +void DocumentDBInsertTest::SetUp(void) {} + +void DocumentDBInsertTest::TearDown(void) {} + +/** + * @tc.name: DocumentDBInsertTest001 + * @tc.desc: Insert documents into collection which dose not exist + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest001, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert document into collection which dose not exist + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"1\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, NO_EXIST_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest002 + * @tc.desc: Insert documents into collection which _id is not string + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest002, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a document whose _id is integer + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : 2, \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Insert a document whose _id is bool + * @tc.expected:step2.GRD_INVALID_ARGS + */ + const char *document2 = "{\"_id\" : true, \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Insert a document whose _id is NULL + * @tc.expected:step2.GRD_INVALID_ARGS + */ + const char *document3 = "{\"_id\" : null, \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document3, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Insert a document whose _id is ARRAY + * @tc.expected:step2.GRD_INVALID_ARGS + */ + const char *document4 = "{\"_id\" : [\"2\"], \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document4, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Insert a document whose _id is OBJECT + * @tc.expected:step2.GRD_INVALID_ARGS + */ + const char *document5 = "{\"_id\" : {\"val\" : \"2\"}, \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document5, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest003 + * @tc.desc: Insert a document whose _id has appeared before + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest003, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a document whose _id is string + * @tc.expected:step1.GRD_OK + */ + const char *document1 = "{\"_id\" : \"3\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); + + /** + * @tc.steps:step2.Insert a document whose _id has appeared before + * @tc.expected:step2.GRD_DATA_CONFLICT + */ + const char *document2 = "{\"_id\" : \"3\", \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_DATA_CONFLICT); +} + +/** + * @tc.name: DocumentDBInsertTest004 + * @tc.desc: Test Insert with null parameter. parameter db is NULL + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest004, TestSize.Level1) +{ + /** + * @tc.steps:step1.step1.parameter db is NULL + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"4\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(NULL, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest005 + * @tc.desc: Test insert with null parameter. parameter collectionName is NULL. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest005, TestSize.Level1) +{ + /** + * @tc.steps:step1.Parameter collectionName is NULL + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"5\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, NULL, document1, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Parameter collectionName is empty string + * @tc.expected:step2.GRD_INVALID_ARGS + */ + const char *document2 = "{\"_id\" : \"5\", \"name\" : \"Chuang\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, "", document2, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest006 + * @tc.desc: parameter flags is not zero + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest006, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter flags is not zero + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"6\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 1), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest007 + * @tc.desc: parameter flags is INT_MAX + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest007, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter flags is int_max + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"7\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, INT_MAX), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest008 + * @tc.desc: parameter flags is int_min + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest008, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter flags is int_min + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = "{\"_id\" : \"8\", \"name\" : \"Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, INT_MIN), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest009 + * @tc.desc: parameter collectionName and document is NULL or invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest009, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter collectionName and document is NULL; + * @tc.expected:step1.GRD_INVALID_ARGS + */ + EXPECT_EQ(GRD_InsertDoc(g_db, NULL, NULL, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.parameter collectionName is larger than max_collectionName_lens; + * @tc.expected:step2.GRD_OVER_LIMIT + */ + const char *document1 = "{\"_id\" : \"9\", \"name\" : \"Ori\"}"; + std::string collectionName2(MAX_COLLECTION_LENS + 1, 'a'); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName2.c_str(), document1, 0), GRD_OVER_LIMIT); +} + +/** + * @tc.name: DocumentDBInsertTest010 + * @tc.desc: parameter collectionName contains irregular charactor + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest010, TestSize.Level1) +{ + /** + * @tc.steps:step1.Create Collection whose parameter collectionName contains irregular charactor + * @tc.expected:step1.GRD_OK + */ + const char *collectionName = "collction@!#"; + const char *document1 = "{\"_id\" : \"10\", \"name\" : \"Ori\"}"; + TestInsertDocIntoCertainColl(collectionName, document1, GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest011 + * @tc.desc: parameter collectionName is longer than 256 charactors + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest011, TestSize.Level1) +{ + /** + * @tc.steps:step1.Create Collection whose parameter collectionName contains irregular charactor + * @tc.expected:step1.GRD_OK + */ + string collectionName(257, 'k'); + const char *document1 = "{\"_id\" : \"10\", \"name\" : \"Ori\"}"; + TestInsertDocIntoCertainColl(collectionName.c_str(), document1, GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest014 + * @tc.desc: Inserted document's JSON depth is larger than 4, which is 5. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest014, TestSize.Level1) +{ + /** + * @tc.steps:step1.document's JSON depth is larger than 4, which is 5. + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document1 = R""({"level1" : {"level2" : {"level3" : {"level4": {"level5" : 1}}, + "level3_2" : "level3_2_val"}},"_id":"14"})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step1.document's JSON depth is larger than 4, which is 5.But with array type. + * @tc.expected:step1.GRD_INVALID_ARGS + */ + const char *document2 = R""({"level1" : {"level2" : {"level3" : [{ "level5" : "level5_1val", + "level5_2":"level5_2_val"}, "level4_val1","level4_val2"], "level3_2" : "level3_2_val"}}, "_id":"14"})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step1.document's JSON depth is 4 + * @tc.expected:step1.GRD_OK + */ + const char *document3 = R""({"level1" : {"level2" : {"level3" : { "level4" : "level5_1val"}, + "level3_2" : "level3_2_val"}}, "_id":"14"})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document3, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest015 + * @tc.desc: Inserted document with all kinds of size + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest015, TestSize.Level1) +{ + /** + * @tc.steps:step1.document's JSON is bigger than 512k - 1 + * @tc.expected:step1.GRD_INVALID_ARGS + */ + string documentPart1 = "{ \"_id\" : \"15\", \"textVal\" : \" "; + string documentPart2 = "\" }"; + string jsonVal = string(512 * 1024 - documentPart1.size() - documentPart2.size(), 'k'); + string document = documentPart1 + jsonVal + documentPart2; + /** + * @tc.steps:step2.Insert document's JSON is a large data but lower than 512k - 1 + * @tc.expected:step2.GRD_OK + */ + string jsonVal2 = string(512 * 1024 - 1 - documentPart1.size() - documentPart2.size(), 'k'); + string document2 = documentPart1 + jsonVal2 + documentPart2; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2.c_str(), 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest016 + * @tc.desc: document JSON string contains irregular char + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest016, TestSize.Level1) +{ + /** + * @tc.steps:step1.document JSON string contains irregular char. + * @tc.expected:step1.GRD_OK + */ + const char *document1 = "{\"_id\" : \"16\", \"name\" : \"!@#Ori\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest017 + * @tc.desc: document JSON string contains invalid value type such as BLOB type + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest017, TestSize.Level1) +{ + /** + * @tc.steps:step1.document JSON string contains invalid value type such as BLOB type. + * @tc.expected:step1.GRD_INVALID_FORMAT. + */ + const char *document = "{\"_id\" : \"17\", \"level1\" : {\"level2\" : {\"level3\" : {\"level4\" : x'1234'\ + } } }, \"level1_2\" : \"level1_2Val\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document, 0), GRD_INVALID_FORMAT); +} + +/** + * @tc.name: DocumentDBInsertTest018 + * @tc.desc: The Inserted document is not JSON format + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest018, TestSize.Level1) +{ + /** + * @tc.steps:step1.The Inserted document is not JSON format + * @tc.expected:step1.GRD_INVALID_FORMAT. + */ + const char *document = "some random string not JSON format"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document, 0), GRD_INVALID_FORMAT); +} + +/** + * @tc.name: DocumentDBInsertTest019 + * @tc.desc: Insert a normal documents + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest019, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a normal documents which _id is in the end of the string + * @tc.expected:step1.GRD_OK. + */ + const char *document1 = "{\"name\" : \"Jack\", \"age\" : 18, \"friend\" : {\"name\" : \" lucy\"}, \"_id\" : " + "\"19\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest022 + * @tc.desc: parameter collectionName is equal to 256 charactors + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest022, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter collectionName is equal to 256 charactors + * @tc.expected:step1.GRD_OK. + */ + string collectionName = string(256, 'k'); + string collectionName1(MAX_COLLECTION_LENS, 'a'); + const char *document1 = "{\"_id\" : \"22\", \"name\" : \"Ori\"}"; + TestInsertDocIntoCertainColl(collectionName.c_str(), document1, GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest023 + * @tc.desc: parameter collectionName contains upper & lower case charactors, + * numbers and underline + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest023, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter collectionName contains upper & lower case charactors, + * numbers and underline + * @tc.expected:step1.GRD_OK. + */ + string collectionName = "Aads_sd__23Asb_"; + const char *document1 = "{\"_id\" : \"23\", \"name\" : \"Ori\"}"; + TestInsertDocIntoCertainColl(collectionName.c_str(), document1, GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest024 + * @tc.desc: parameter collectionName's head is GRD_ or GM_SYS_ + * numbers and underline + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest024, TestSize.Level1) +{ + /** + * @tc.steps:step1.parameter collectionName's head is GRD_ + * @tc.expected:step1.GRD_INVALID_FORMAT. + */ + string collectionName = "GRD_collectionName"; + const char *document1 = "{\"_id\" : \"24\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document1, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step2.parameter collectionName's head is GM_SYS_ + * @tc.expected:step2.GRD_INVALID_FORMAT. + */ + collectionName = "GM_SYS__collectionName"; + const char *document2 = "{\"_id\" : \"24_2\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document2, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step3.parameter collectionName's head is grd_ + * @tc.expected:step3.GRD_INVALID_FORMAT. + */ + collectionName = "grd_collectionName"; + const char *document3 = "{\"_id\" : \"24_3\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document3, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step4.parameter collectionName's head is gm_sys_ + * @tc.expected:step4.GRD_INVALID_FORMAT. + */ + collectionName = "gm_sys_collectionName"; + const char *document4 = "{\"_id\" : \"24_4\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document4, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step5.parameter collectionName's head is gM_sYs_ that has Uppercase and lowercase at the same time. + * @tc.expected:step5.GRD_INVALID_FORMAT. + */ + collectionName = "gM_sYs_collectionName"; + const char *document5 = "{\"_id\" : \"24_5\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document5, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step6.parameter collectionName's head is gRd_ that has Uppercase and lowercase at the same time. + * @tc.expected:step6.GRD_INVALID_FORMAT. + */ + collectionName = "gRd_collectionName"; + const char *document6 = "{\"_id\" : \"24_6\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document6, 0), GRD_INVALID_FORMAT); + + /** + * @tc.steps:step7.parameter collectionName's head is grd@ that has no '_' + * @tc.expected:step7.GRD_INVALID_FORMAT. + */ + collectionName = "gRd@collectionName"; + const char *document7 = "{\"_id\" : \"24_7\", \"name\" : \"Ori\"}"; + GRD_CreateCollection(g_db, collectionName.c_str(), "", 0); + EXPECT_EQ(GRD_InsertDoc(g_db, collectionName.c_str(), document7, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest025 + * @tc.desc: Insert document whose depth is 4, which is allowed + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest025, TestSize.Level1) +{ + /** + * @tc.steps:step1.documents JSON depth is 4, which is allowed. + * @tc.expected:step1.GRD_OK. + */ + const char *document1 = "{\"_id\" : \"25_0\", \"level1\" : {\"level2\" : {\"level3\" :\ + {\"level4\" : \"level4Val\"}}} , \"level1_2\" : \"level1_2Val\" }"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); + /** + * @tc.steps:step2.documents JSON depth is exactly 4. + * @tc.expected:step2.GRD_OK. + */ + const char *document2 = "{\"_id\" : \"25_1\", \"class_name\" : \"计算机科学一班\", \"signed_info\" : true, \ + \"student_info\" : [{\"name\":\"张三\", \"age\" : 18, \"sex\" : \"男\"}, \ + { \"newName1\" : [\"qw\", \"dr\", 0, \"ab\"] }]}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_OK); + /** + * @tc.steps:step3.documents JSON depth is exactly 4, but the last field in array contains leading number + * @tc.expected:step3.GRD_INVALID_ARGS. + */ + const char *document3 = "{\"_id\" : \"25_2\", \"class_name\" : \"计算机科学一班\", \"signed_info\" : true, \ + \"student_info\" : [{\"name\":\"张三\", \"age\" : 18, \"sex\" : \"男\"}, \ + [\"qw\", \"dr\", 0, \"ab\", {\"0ab\" : null}]]}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document3, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step4.documents JSON depth is exactly 5. + * @tc.expected:step4.GRD_INVALID_ARGS. + */ + const char *document4 = "{\"_id\" : \"25_3\", \"class_name\" : \"计算机科学一班\", \"signed_info\" : true, \ + \"student_info\" : [{\"name\":\"张三\", \"age\" : 18, \"sex\" : \"男\"}, \ + { \"newName1\" : [\"qw\", \"dr\", 0, \"ab\", {\"level5\" : 1}] }]}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document4, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest026 + * @tc.desc: Insert 100 normal documents continuously + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert 100 normal documents continuously + * @tc.expected:step1.GRD_OK. + */ + string document1 = "{\"_id\" : "; + string document2 = "\""; + string document4 = "\""; + string document5 = ", \"name\" : \"Ori\"}"; + for (int i = 0; i < 5; i++) { + string document_midlle = "26" + std::to_string(i); + string document = document1 + document2 + document_midlle + document4 + document5; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document.c_str(), 0), GRD_OK); + } +} + +/** + * @tc.name: DocumentDBInsertTest035 + * @tc.desc: Insert a document whose value contains + * upper &lower case charactors, numbers and underline. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest035, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a document whose value contains + * upper &lower case charactors, numbers and underline. + * @tc.expected:step1.GRD_OK. + */ + const char *document1 = "{\"_id\" : \"35\", \"A_aBdk_324_\" : \"value\", \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); + /** + * @tc.steps:step1.Insert a document whose value contains + * upper &lower case charactors, numbers and underline. + * But the field started with number, which is not allowed. + * @tc.expected:step1.GRD_OK. + */ + const char *document2 = "{\"_id\" : \"35_2\", \"1A_aBdk_324_\" : \"value\", \"name\" : \"Chuan\"}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentDBInsertTest036 + * @tc.desc: Insert a document whose value contains + * string, number, bool, null, array and object type + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest036, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a document whose value contains + * string, number, bool, null, array and object type + * @tc.expected:step1.GRD_OK. + */ + const char *document1 = "{\"_id\" : \"36_0\", \"stringType\" : \"stringVal\", \"numType\" : 1, \"BoolType\" : true,\ + \"nullType\" : null, \"arrayType\" : [1, 2, 3, 4], \"objectType\" : {\"A\" : 3}}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest038 + * @tc.desc: Insert document whose value is over the range of double + * string, number, bool, null, array and object type + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest038, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert document whose value is over the range of double + * @tc.expected:step1.GRD_INVALID_ARGS. + */ + const char *document1 = R"({"_id" : "38_0", "field2" : 1.79769313486232e308})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step2.Insert document whose value is over the range of double + * @tc.expected:step2.GRD_INVALID_ARGS. + */ + const char *document2 = R"({"_id" : "38_1", "t1" : {"field2" : 1.79769313486232e308}})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step3.Insert document whose value is over the range of double + * @tc.expected:step3.GRD_INVALID_ARGS. + */ + const char *document3 = R"({"_id" : "38_2", "t1" : [1, 2, 1.79769313486232e308]})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document3, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step4.Insert document whose value is over the range of double + * @tc.expected:step4.GRD_INVALID_ARGS. + */ + const char *document4 = R"({"_id" : "38_3", "t1" : [1, 2, -1.7976931348623167E+308]})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document4, 0), GRD_INVALID_ARGS); + /** + * @tc.steps:step5.Insert document with minimum double value + * @tc.expected:step5.GRD_INVALID_ARGS. + */ + const char *document5 = R"({"_id" : "38_4", "t1" : [1, 2, -1.79769313486231570E+308]})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document5, 0), GRD_OK); + /** + * @tc.steps:step6.Insert document with maxium double value + * @tc.expected:step6.GRD_INVALID_ARGS. + */ + const char *document6 = R"({"_id" : "38_5", "t1" : [1, 2, 1.79769313486231570E+308]})"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document6, 0), GRD_OK); +} + +/** + * @tc.name: DocumentDBInsertTest039 + * @tc.desc: Insert a filter which _id value's lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest039, TestSize.Level1) +{ + /** + * @tc.steps:step1.Insert a filter which _id value's lens is larger than MAX_ID_LENS. + * @tc.expected:step1.GRD_OVER_LIMIT. + */ + string document1 = "{\"_id\" : "; + string document2 = "\""; + string document4 = "\""; + string document5 = ", \"name\" : \"Ori\"}"; + string document_midlle(MAX_ID_LENS + 1, 'k'); + string document = document1 + document2 + document_midlle + document4 + document5; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document.c_str(), 0), GRD_OVER_LIMIT); + + /** + * @tc.steps:step1.Insert a filter which _id value's lens is equal as MAX_ID_LENS. + * @tc.expected:step1.GRD_OK. + */ + string document_midlle2(MAX_ID_LENS, 'k'); + document = document1 + document2 + document_midlle2 + document4 + document5; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document.c_str(), 0), GRD_OK); +} + +/** + * @tc.name: DocumentUpdataApiTest040 + * @tc.desc: Insert a filter which _id value's lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest040, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"1\"}"; + const char *updata2 = "{\"objectInfo.child.child\" : {\"child\":{\"child\":null}}}"; + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata2, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentUpdataApiTest041 + * @tc.desc: Insert a filter which _id value's lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest041, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"1\"}"; + const char *updata1 = "{\"_id\" : \"6\"}"; + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata1, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentUpdataApiTest042 + * @tc.desc: Insert a filter which _id value's lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest042, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"1\"}"; + const char *updata1 = "{\"age$\" : \"21\"}"; + const char *updata2 = "{\"bonus..traffic\" : 100}"; + const char *updata3 = "{\"0item\" : 100}"; + const char *updata4 = "{\"item\" : 1.79769313486232e308}"; + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata2, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata3, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, updata4, 0), GRD_INVALID_ARGS); +} + +/** + * @tc.name: DocumentUpdataApiTest043 + * @tc.desc: Insert a filter which _id value's lens is larger than MAX_ID_LENS + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest043, TestSize.Level1) +{ + const char *filter = "{\"_id\" : \"1\"}"; + const char *updata1 = "{\"age\" : 21}"; + EXPECT_EQ(GRD_UpdateDoc(g_db, NULL, filter, updata1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, "", filter, updata1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(NULL, RIGHT_COLLECTION_NAME, filter, updata1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, NULL, updata1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_UpdateDoc(g_db, RIGHT_COLLECTION_NAME, filter, NULL, 0), GRD_INVALID_ARGS); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest044, TestSize.Level1) +{ + const char *document1 = R""({"_id":"0123", "num":"num"})""; + const char *document2 = R""({"_id":"0123", "NUM":"No.45"})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_DATA_CONFLICT); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest045, TestSize.Level1) +{ + const char *document1 = R""({"_id":"0123", "num.":"num"})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest046, TestSize.Level1) +{ + const char *document1 = R""({})""; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest047, TestSize.Level1) +{ + const char *document1 = "{\"empty\" : null}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} +} // namespace diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.h b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_test_utils.h similarity index 99% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.h rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_test_utils.h index a513875ef87a922f39132229a2e9e620f2bda17c..b1dc3f516b59db00e5cd2cf3643e631ecece1eb8 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_test_utils.h @@ -17,7 +17,6 @@ #define DOCUMENTDB_TEST_UTILS_H #include - namespace DocumentDBUnitTest { class DocumentDBTestUtils { public: diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp similarity index 92% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp index f26640ad80bac465982013d705abb7d391323499..0a5531c5c620f7930ff798d5385714451b37e390 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/common/documentdb_test_utils.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.cpp @@ -18,7 +18,7 @@ namespace DocumentDBUnitTest { int DocumentDBTestUtils::RemoveTestDbFiles(const std::string &dir) { - (void)remove(dir.c_str()); // TODO: remove dir or files + (void)remove(dir.c_str()); return 0; } } // namespace DocumentDBUnitTest \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.h b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..b1dc3f516b59db00e5cd2cf3643e631ecece1eb8 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/common/documentdb_test_utils.h @@ -0,0 +1,26 @@ +/* +* 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 DOCUMENTDB_TEST_UTILS_H +#define DOCUMENTDB_TEST_UTILS_H +#include + +namespace DocumentDBUnitTest { +class DocumentDBTestUtils { +public: + static int RemoveTestDbFiles(const std::string &dir); +}; +} // namespace DocumentDBUnitTest +#endif // DOCUMENTDB_TEST_UTILS_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp similarity index 30% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp index 11717fe75652d63513e1ad8b579825b993cdb35b..ff4820e9c55afd4166a3c7c835706fa5b61ddc06 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -16,8 +16,8 @@ #include #include -#include "documentdb_test_utils.h" #include "doc_errno.h" +#include "documentdb_test_utils.h" #include "json_common.h" #include "log_print.h" @@ -25,6 +25,7 @@ using namespace DocumentDB; using namespace testing::ext; using namespace DocumentDBUnitTest; +namespace { class DocumentDBJsonCommonTest : public testing::Test { public: static void SetUpTestCase(void); @@ -33,33 +34,19 @@ public: void TearDown(); }; -void DocumentDBJsonCommonTest::SetUpTestCase(void) -{ -} +void DocumentDBJsonCommonTest::SetUpTestCase(void) {} -void DocumentDBJsonCommonTest::TearDownTestCase(void) -{ -} +void DocumentDBJsonCommonTest::TearDownTestCase(void) {} -void DocumentDBJsonCommonTest::SetUp(void) -{ -} +void DocumentDBJsonCommonTest::SetUp(void) {} -void DocumentDBJsonCommonTest::TearDown(void) -{ -} +void DocumentDBJsonCommonTest::TearDown(void) {} -/** - * @tc.name: OpenDBTest001 - * @tc.desc: Test open document db - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest001, TestSize.Level0) { - std::string document = R""({"name":"Tmn","age":18,"addr":{"city":"shanghai","postal":200001}})""; - std::string updateDoc = R""({"name":"Xue","case":{"field1":1,"field2":"string","field3":[1,2,3]},"age":28,"addr":{"city":"shenzhen","postal":518000}})""; + std::string document = R""({"name":"Tmn", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; + std::string updateDoc = R""({"name":"Xue", "case":{"field1":1, "field2":"string", "field3":[1, 2, 3]}, + "age":28, "addr":{"city":"shenzhen", "postal":518000}})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -67,60 +54,62 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest001, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"case", "field1"}, errCode); + JsonObject itemCase = src.FindItem({ "case", "field1" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetIntValue(), 1); - JsonObject itemName = src.FindItem({"name"}, errCode); + JsonObject itemName = src.FindItem({ "name" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemName.GetItemValue().GetStringValue(), "Xue"); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest002, TestSize.Level0) { - std::string document = R""({"name":"Tmn","case":2,"age":[1,2,3],"addr":{"city":"shanghai","postal":200001}})""; - std::string updateDoc = R""({"name":["Xue","Neco","Lip"],"grade":99,"age":18,"addr": - [{"city":"shanghai","postal":200001},{"city":"beijing","postal":100000}]})""; + std::string document = R""({"name":"Tmn", "case":2, "age":[1, 2, 3], + "addr":{"city":"shanghai", "postal":200001}})""; + std::string updateDoc = R""({"name":["Xue", "Neco", "Lip"], "grade":99, "age":18, "addr": + [{"city":"shanghai", "postal":200001}, {"city":"beijing", "postal":100000}]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"grade"}, errCode); + JsonObject itemCase = src.FindItem({ "grade" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetIntValue(), 99); // 99: grade - JsonObject itemName = src.FindItem({"name", "1"}, errCode); + JsonObject itemName = src.FindItem({ "name", "1" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemName.GetItemValue().GetStringValue(), "Neco"); } - HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest003, TestSize.Level0) { - std::string document = R""({"name":["Tmn","BB","Alice"],"age":[1,2,3],"addr":[{"city":"shanghai","postal":200001},{"city":"wuhan","postal":430000}]})""; - std::string updateDoc = R""({"name":["Xue","Neco","Lip"],"age":18,"addr":[{"city":"shanghai","postal":200001},{"city":"beijing","postal":100000}]})""; + std::string document = R""({"name":["Tmn", "BB", "Alice"], "age":[1, 2, 3], + "addr":[{"city":"shanghai", "postal":200001}, {"city":"wuhan", "postal":430000}]})""; + std::string updateDoc = R""({"name":["Xue", "Neco", "Lip"], "age":18, "addr":[{"city":"shanghai", "postal":200001}, + {"city":"beijing", "postal":100000}]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"addr", "1", "city"}, errCode); + JsonObject itemCase = src.FindItem({ "addr", "1", "city" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "beijing"); // 99: grade - JsonObject itemName = src.FindItem({"name", "1"}, errCode); + JsonObject itemName = src.FindItem({ "name", "1" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemName.GetItemValue().GetStringValue(), "Neco"); } @@ -128,21 +117,21 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest003, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest004, TestSize.Level0) { std::string document = R""({"name":["Tmn","BB","Alice"]})""; - std::string updateDoc = R""({"name.5":"GG"})"";; + std::string updateDoc = R""({"name.5":"GG"})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), -E_DATA_CONFLICT); + EXPECT_EQ(JsonCommon::Append(src, add, false), -E_NO_DATA); GLOGD("result: %s", src.Print().c_str()); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest005, TestSize.Level0) { - std::string document = R""({"name":["Tmn","BB","Alice"]})""; - std::string updateDoc = R""({"name.2":"GG"})"";; + std::string document = R""({"name":["Tmn", "BB", "Alice"]})""; + std::string updateDoc = R""({"name.2":"GG"})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -150,36 +139,17 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest005, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "2"}, errCode); - EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); -} - -HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest006, TestSize.Level0) -{ - std::string document = R""({"name":{"first":"Tno","last":"moray"}})""; - std::string updateDoc = R""({"name":{"midle.AA":"GG"}})""; - - int errCode = E_OK; - JsonObject src = JsonObject::Parse(document, errCode); - EXPECT_EQ(errCode, E_OK); - JsonObject add = JsonObject::Parse(updateDoc, errCode); - EXPECT_EQ(errCode, E_OK); - - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); - GLOGD("result: %s", src.Print().c_str()); - - JsonObject itemCase = src.FindItem({"name", "midle.AA"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "2" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest007, TestSize.Level0) { - std::string document = R""({"name":{"first":["XX","CC"],"last":"moray"}})""; + std::string document = R""({"name":{"first":["XX", "CC"], "last":"moray"}})""; std::string updateDoc = R""({"name.first.0":"LL"})""; int errCode = E_OK; @@ -188,18 +158,18 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest007, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "first", "0"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "first", "0" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "LL"); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest008, TestSize.Level0) { - std::string document = R""({"name":{"first":"XX","last":"moray"}})""; - std::string updateDoc = R""({"name":{"first":["XXX","BBB","CCC"]}})""; + std::string document = R""({"name":{"first":"XX", "last":"moray"}})""; + std::string updateDoc = R""({"name":{"first":["XXX", "BBB", "CCC"]}})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -207,18 +177,17 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest008, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "first", "0"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "first", "0" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "XXX"); } - HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest009, TestSize.Level0) { - std::string document = R""({"name":{"first":["XXX","BBB","CCC"],"last":"moray"}})""; + std::string document = R""({"name":{"first":["XXX", "BBB", "CCC"], "last":"moray"}})""; std::string updateDoc = R""({"name":{"first":"XX"}})""; int errCode = E_OK; @@ -227,10 +196,10 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest009, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "first"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "first" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "XX"); } @@ -246,10 +215,10 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest010, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "first", "XX"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "first", "XX" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "AA"); } @@ -265,66 +234,360 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest011, TestSize.Level0) JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), -E_DATA_CONFLICT); + EXPECT_EQ(JsonCommon::Append(src, add, false), -E_DATA_CONFLICT); GLOGD("result: %s", src.Print().c_str()); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest012, TestSize.Level0) { std::string document = R""({"name":["Tmn","BB","Alice"]})""; - std::string updateDoc = R""({"name.first":"GG"})"";; + std::string updateDoc = R""({"name.first":"GG"})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), -E_DATA_CONFLICT); + EXPECT_EQ(JsonCommon::Append(src, add, false), -E_DATA_CONFLICT); GLOGD("result: %s", src.Print().c_str()); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest013, TestSize.Level0) { std::string document = R""({"name":["Tmn","BB","Alice"]})""; - std::string updateDoc = R""({"name":{"first":"GG"}})"";; + std::string updateDoc = R""({"name":{"first":"GG"}})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest014, TestSize.Level0) { - std::string document = R""({"name":{"first":"Xue","second":"Lang"}})""; - std::string updateDoc = R""({"name.0":"GG"})"";; + std::string document = R""({"name":{"first":"Xue", "second":"Lang"}})""; + std::string updateDoc = R""({"name.0":"GG"})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), -E_DATA_CONFLICT); + EXPECT_EQ(JsonCommon::Append(src, add, false), -E_DATA_CONFLICT); GLOGD("result: %s", src.Print().c_str()); } HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest015, TestSize.Level0) { std::string document = R""({"name":{"first":"Xue","second":"Lang"}})""; - std::string updateDoc = R""({"name.first":["GG","MM"]})"";; + std::string updateDoc = R""({"name.first":["GG", "MM"]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); JsonObject add = JsonObject::Parse(updateDoc, errCode); EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(JsonCommon::Append(src, add), E_OK); + EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); GLOGD("result: %s", src.Print().c_str()); - JsonObject itemCase = src.FindItem({"name", "first", "0"}, errCode); + JsonObject itemCase = src.FindItem({ "name", "first", "0" }, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); -} \ No newline at end of file +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest001, TestSize.Level0) +{ + std::string document = R""({"name":{"first": {"job" : "it"}}, "t1" : {"second":"Lang"}})""; + std::string filter = R""({"name":{"first": {"job" : "it"}}, "t1" : {"second":"Lang"}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); + + std::string document2 = R""({"name":{"first": {"job" : "it"}, "t1" : {"second":"Lang"}}})""; + std::string filter2 = R""({"name":{"first": {"job" : "NoEqual"}}, "t1" : {"second":"Lang"}})""; + int errCode2 = E_OK; + JsonObject srcObj2 = JsonObject::Parse(document2, errCode2); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj2 = JsonObject::Parse(filter2, errCode2); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj2, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest002, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock": {"warehouse":"A", "qty":5}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest003, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": "GG"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest004, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": "GG"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest005, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", "AA"], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": ["GG", "AA"]})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest006, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl"}], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item.0": "GG"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest007, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl"}], "instock": [{"warehouse":"A", "qty":5}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": ["GG", {"gender":"girl"}]})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest008, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": + [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": {"gender":"girl"}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest009, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": + [{"qty" : 16, "warehouse":"A"}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock.warehouse": "A"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest010, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": [{"warehouse":"A"}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock.warehouse": "C"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest011, TestSize.Level0) +{ + std::string document = + R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock" : {"warehose" : "A", "qty" : 5}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest012, TestSize.Level0) +{ + std::string document = + R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock" : {"warehose" : "A", "bad" : "2" , "qty" : 5}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest013, TestSize.Level0) +{ + std::string document = + R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock.qty" : 15})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest014, TestSize.Level0) +{ + std::string document = + R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock.1.qty" : 15})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest015, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "tags" : ["blank", "red"], "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : ["blank", "red"]})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest016, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "tags" : {"value" : null}, "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : {"value" : null}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest017, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : {"value" : null}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest018, TestSize.Level0) +{ + std::string document = "{\"_id\" : \"2\", \"name\":\"doc2\",\"item\": 1, \"personInfo\":\ + [1, \"my string\", {\"school\":\"AB\", \"age\" : 51}, true, {\"school\":\"CD\", \"age\" : 15}, false]}"; + std::string filter = R""({"_id" : "2"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest019, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"1\", \"name\":\"doc1\",\"item\":\"journal\",\"personInfo\":\ + {\"school\":\"AB\", \"age\" : 51}}"; + const char *filter = "{\"personInfo.school\" : \"AB\"}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest020, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"3\", \"name\":\"doc3\",\"item\":\"notebook\",\"personInfo\":\ + [{\"school\":\"C\", \"age\" : 5}]}"; + const char *filter = "{\"personInfo\" : [{\"school\":\"C\", \"age\" : 5}]}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest021, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"15\", \"name\":\"doc15\",\"personInfo\":[{\"school\":\"C\", \"age\" : 5}]}"; + const char *filter = "{\"item\" : null, \"personInfo\" : [{\"school\":\"C\", \"age\" : 5}]}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest022, TestSize.Level0) +{ + string document = R"({"_id" : "001", "key1" : {"key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}, + "k22" : "v22"}, "k12" : "v12"})"; + string document2 = R"({"_id" : "002", "key1" : {"key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}}, + "k12" : "v12"})"; + const char *filter = R"({"key1" : {"key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}}})"; + const char *filter2 = R"({"key1" : {"k22" : "v22", "key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, + "k32" : "v32"}}})"; + int errCode = E_OK; + JsonObject srcObj1 = JsonObject::Parse(document, errCode); + JsonObject srcObj2 = JsonObject::Parse(document2, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj1 = JsonObject::Parse(filter, errCode); + JsonObject filterObj2 = JsonObject::Parse(filter2, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj1, errCode), false); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj1, errCode), true); + + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj2, errCode), true); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj2, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest023, TestSize.Level0) +{ + string document = R"({"_id" : "001", "key1" : {"key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}, + "k22" : "v22"}, "k12" : "v12", "key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}})"; + string document2 = R"({"_id" : "002", "key1" : {"key2" : {"key3" : {"key4" : 123}, "k32" : "v32"}, "k22" : "v22"}, + "k12" : "v12"})"; + const char *filter = R"({"key2" : {"key3" : {"key4" : 123, "k42" : "v42"}, "k32" : "v32"}})"; + int errCode = E_OK; + JsonObject srcObj1 = JsonObject::Parse(document, errCode); + JsonObject srcObj2 = JsonObject::Parse(document2, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj1 = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj1, errCode), true); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj1, errCode), false); +} +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp similarity index 79% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp index fa16a27a019fc874f28bff8beef2a4bc71208ffa..604f2c386eeb5e9d5a9f019633c9dcc4404be2ab 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp @@ -14,14 +14,16 @@ */ #include -#include "documentdb_test_utils.h" + #include "doc_errno.h" +#include "documentdb_test_utils.h" #include "json_object.h" using namespace DocumentDB; using namespace testing::ext; using namespace DocumentDBUnitTest; +namespace { class DocumentDBJsonObjectTest : public testing::Test { public: static void SetUpTestCase(void); @@ -30,21 +32,13 @@ public: void TearDown(); }; -void DocumentDBJsonObjectTest::SetUpTestCase(void) -{ -} +void DocumentDBJsonObjectTest::SetUpTestCase(void) {} -void DocumentDBJsonObjectTest::TearDownTestCase(void) -{ -} +void DocumentDBJsonObjectTest::TearDownTestCase(void) {} -void DocumentDBJsonObjectTest::SetUp(void) -{ -} +void DocumentDBJsonObjectTest::SetUp(void) {} -void DocumentDBJsonObjectTest::TearDown(void) -{ -} +void DocumentDBJsonObjectTest::TearDown(void) {} /** * @tc.name: OpenDBTest001 @@ -55,14 +49,15 @@ void DocumentDBJsonObjectTest::TearDown(void) */ HWTEST_F(DocumentDBJsonObjectTest, JsonObjectTest001, TestSize.Level0) { - const std::string config = R""({"a":123,"b":{"c":234,"d":"12345"}})""; + const std::string config = R""({"a":123, "b":{"c":234, "d":"12345"}})""; int ret = E_OK; JsonObject conf = JsonObject::Parse(config, ret); EXPECT_EQ(ret, E_OK); - ValueObject obj = conf.GetObjectByPath({"b", "c"}, ret); + ValueObject obj = conf.GetObjectByPath({ "b", "c" }, ret); EXPECT_EQ(obj.GetValueType(), ValueObject::ValueType::VALUE_NUMBER); EXPECT_EQ(obj.GetIntValue(), 234); -} \ No newline at end of file +} +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7121f15cbb3f0a5598dcb8aa2c8412ac8ef5427f --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp @@ -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. +*/ + +#include +#include + +#include "doc_errno.h" +#include "document_key.h" +#include "documentdb_test_utils.h" +#include "log_print.h" + +using namespace DocumentDB; +using namespace testing::ext; +using namespace DocumentDBUnitTest; + +namespace { +class DocumentDBKeyCommonTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DocumentDBKeyCommonTest::SetUpTestCase(void) {} + +void DocumentDBKeyCommonTest::TearDownTestCase(void) {} + +void DocumentDBKeyCommonTest::SetUp(void) {} + +void DocumentDBKeyCommonTest::TearDown(void) {} + +} // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/CMakeLists.txt b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/CMakeLists.txt deleted file mode 100644 index cb213c24cf765bf138f42845a5e21ee87724535b..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/CMakeLists.txt +++ /dev/null @@ -1,209 +0,0 @@ -cmake_minimum_required(VERSION 3.2) - -project(grd_simple VERSION 1.0.0) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -std=c++17 -pthread") - -# Address Sanitizer -option(USE_ASAN "Compile with address sanitiser" OFF) -if (USE_ASAN) - message(STATUS "Compile with address sanitiser ${USE_ASAN}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -O0") -endif() - -function(download_repo repo_name repo_url) - execute_process( - COMMAND [ -d ${repo_name} ] - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party - RESULT_VARIABLE REPO_EXISTS - ) - message(STATUS "check ${repo_name} exists result: ${REPO_EXISTS}") - if (NOT (${REPO_EXISTS} EQUAL 0)) - message(STATUS "Downloading ${repo_name} from ${repo_url}") - execute_process( - COMMAND git clone ${repo_url} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party - ) - message(STATUS "Download ${repo_name} finished") - endif() -endfunction(download_repo) - -function(build_repo repo_name script_path) - execute_process( - COMMAND [ -f ${repo_name}/Makefile ] - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party - RESULT_VARIABLE SCRIPT_EXISTS - ) - if (NOT (${SCRIPT_EXISTS} EQUAL 0)) - message(STATUS "Copy build script ${script_path}/Makefile to repo ${repo_name}") - execute_process( - COMMAND cp third_party/kate/${script_path}/Makefile third_party/${repo_name} -f - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - ) - message(STATUS "Build ${repo_name}") - execute_process( - COMMAND make -j9 - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - ) - message(STATUS "Build finished") - endif() -endfunction(build_repo) - -function(cmake_repo repo_name) - execute_process( - COMMAND [ -d ${repo_name}/build ] - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party - RESULT_VARIABLE BUILD_FINISHED - ) - if (NOT (${BUILD_FINISHED} EQUAL 0)) - message(STATUS "compile repo ${repo_name}") - execute_process( - COMMAND mkdir -p build - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - ) - execute_process( - COMMAND cmake .. - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name}/build - ) - execute_process( - COMMAND make -j9 - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name}/build - ) - endif() -endfunction(cmake_repo) - -function(build_openssl repo_name) - execute_process( - COMMAND [ -f Makefile ] - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - RESULT_VARIABLE BUILD_FINISHED - ) - if (NOT (${BUILD_FINISHED} EQUAL 0)) - message(STATUS "compile repo ${repo_name}") - execute_process( - COMMAND chmod +x ./config - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - ) - execute_process( - COMMAND ./config - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - ) - execute_process( - COMMAND make -j9 - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/${repo_name} - ) - endif() -endfunction(build_openssl) - -# create third_party directory -execute_process( - COMMAND mkdir -p ${PROJECT_SOURCE_DIR}/third_party - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} -) - -# Download dependencies -download_repo("third_party_cJSON" "https://gitee.com/openharmony/third_party_cJSON.git") -download_repo("third_party_googletest" "https://gitee.com/openharmony/third_party_googletest.git") -download_repo("third_party_openssl" "https://gitee.com/openharmony/third_party_openssl.git") -download_repo("third_party_sqlite" "https://gitee.com/openharmony/third_party_sqlite.git") -download_repo("utils_native" "https://gitee.com/openharmony/utils_native.git") -download_repo("kate" "https://gitee.com/lianhuix/kate.git") - -# build openssl Makefile -build_openssl("third_party_openssl") - -# build securec -build_repo("utils_native" "securec") - -# build sqlite -build_repo("third_party_sqlite" "sqlite") - -#build googletest -execute_process( - COMMAND sed -i /Wshadow/d internal_utils.cmake - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest/googletest/cmake -) -execute_process( - COMMAND sed -i "s%testing::GTEST_FLAG(output)%// testing::GTEST_FLAG(output)%g" googlemock/src/gmock_main.cc - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest -) -execute_process( - COMMAND sed -i "s%testing::GTEST_FLAG(output)%// testing::GTEST_FLAG(output)%g" googletest/src/gtest_main.cc - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest -) -cmake_repo("third_party_googletest") - -# build cJSON -cmake_repo("third_party_cJSON" "cJSON") - -find_package(Threads) -enable_testing() - -set(DB_PATH ${PROJECT_SOURCE_DIR}/frameworks/libs/distributeddb) - -file(GLOB_RECURSE DOCUMENT_SRC "${PROJECT_SOURCE_DIR}/src/*.cpp") -file(GLOB_RECURSE DOCUMENT_TEST "${PROJECT_SOURCE_DIR}/test/*.cpp") - -include_directories( - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/src/storage - ${PROJECT_SOURCE_DIR}/src/storage/include - ${PROJECT_SOURCE_DIR}/src/storage/src - ${PROJECT_SOURCE_DIR}/src/common - ${PROJECT_SOURCE_DIR}/src/common/include - ${PROJECT_SOURCE_DIR}/src/executor/include - ${PROJECT_SOURCE_DIR}/src/executor/base - ${PROJECT_SOURCE_DIR}/src/executor/document - ${PROJECT_SOURCE_DIR}/src/oh_adapter - ${PROJECT_SOURCE_DIR}/src/oh_adapter/include - ${PROJECT_SOURCE_DIR}/src/oh_adapter/src - ${PROJECT_SOURCE_DIR}/src/interface - ${PROJECT_SOURCE_DIR}/src/interface/include - ${PROJECT_SOURCE_DIR}/src/interface/src -) - -include_directories( - ${PROJECT_SOURCE_DIR}/test/unittest/common -) - -set(DISTRIBUTEDDB_PATH ${PROJECT_SOURCE_DIR}/third_party/distributeddatamgr_kv_store/frameworks/libs/distributeddb/) -include_directories( - ${DISTRIBUTEDDB_PATH}/include - ${DISTRIBUTEDDB_PATH}/interfaces/include -) - -include_directories( - ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest/googletest/include - ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest/googlemock/include - ${PROJECT_SOURCE_DIR}/third_party/third_party_cJSON - ${PROJECT_SOURCE_DIR}/third_party/third_party_sqlite/include - ${PROJECT_SOURCE_DIR}/third_party/utils_native/base/include - ${PROJECT_SOURCE_DIR}/third_party/utils_native/base/src/securec - ${PROJECT_SOURCE_DIR}/third_party/third_party_openssl/include - ${PROJECT_SOURCE_DIR}/third_party/kate/log/include -) - -link_directories( - ${PROJECT_SOURCE_DIR}/third_party/third_party_googletest/build/lib - ${PROJECT_SOURCE_DIR}/third_party/third_party_cJSON/build - ${PROJECT_SOURCE_DIR}/third_party/third_party_openssl - ${PROJECT_SOURCE_DIR}/third_party/third_party_sqlite - ${PROJECT_SOURCE_DIR}/third_party/utils_native -) - -add_executable(document_ut ${DOCUMENT_SRC} ${DOCUMENT_TEST}) - -target_link_libraries(document_ut - cjson - - sqlite3 - securec - ssl - crypto - - gtest - gtest_main - gmock - gmock_main -) - diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/README.md b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/README.md deleted file mode 100644 index 1d777fec2bfb8f35529ccd0cc52f38b3a4790cb8..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/README.md +++ /dev/null @@ -1 +0,0 @@ -# Document DB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/doc_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/doc_common.cpp deleted file mode 100644 index a3dc9d963f69671df8d8fdc44e5a15b26c16ebcd..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/doc_common.cpp +++ /dev/null @@ -1,100 +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. - */ -#include -#include - -#include "doc_common.h" -#include "doc_errno.h" -#include "log_print.h" -#include "securec.h" - -namespace DocumentDB { -namespace { -constexpr const char *COLLECTION_PREFIX_GRD = "GRD_"; -constexpr const char *COLLECTION_PREFIX_GM_SYS = "GM_SYS_"; -const int MAX_COLLECTION_NAME = 512; - -bool CheckCollectionNamePrefix(const std::string &name, const std::string &prefix) -{ - if (name.length() < prefix.length()) { - return false; - } - - auto itPrefix = prefix.begin(); - auto itName = name.begin(); - while (itPrefix != prefix.end()) { - if (std::tolower(*itPrefix) != std::tolower(*itName)) { - return false; - } - itPrefix++; - itName++; - } - return true; -} -} - -bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::string &lowerCaseName, int &errCode) -{ - if (collectionName.empty()) { - errCode = -E_INVALID_ARGS; - return false; - } - if (collectionName.length() + 1 > MAX_COLLECTION_NAME) { - errCode = -E_OVER_LIMIT; - return false; - } - if (CheckCollectionNamePrefix(collectionName, COLLECTION_PREFIX_GRD) || - CheckCollectionNamePrefix(collectionName, COLLECTION_PREFIX_GM_SYS)) { - errCode = -E_INVALID_COLL_NAME_FORMAT; - return false; - } - - lowerCaseName = collectionName; - std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c){ - return std::tolower(c); - }); - return true; -} - -bool CheckCommon::CheckFilter(const std::string &filter) -{ - // if (JsonCommon::CheckIsJson(filter) == false) { - // return false; - // } - // if (JsonCommon::GetJsonDeep(filter) > 4) { - // return false; - // } - // if (CheckIdFormat(filter) == false) { - // return false; - // } - return true; -} - -bool CheckCommon::CheckIdFormat(const std::string &data) -{ - // CjsonObject filter_json; - // filter_json.Parse(data); - // std::vector id; - // if (JsonCommon::GetIdValue(&filter_json, id) == E_ERROR) { - // return false; - // } - return true; -} - -bool CheckCommon::CheckDocument(const std::string &document) -{ - return true; -} -} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp deleted file mode 100644 index 46370a61ce659220fb023798de5b7996c129113a..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp +++ /dev/null @@ -1,253 +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. - */ -#include -#include - -#include "json_common.h" -#include "doc_errno.h" -#include "log_print.h" -#include "securec.h" - -namespace DocumentDB { -ResultValue JsonCommon::GetValueByFiled(JsonObject *node, const std::string& filed) -{ - if (node == nullptr) { - return ResultValue(); - } - while (node != nullptr) { - if (node->GetItemFiled() == filed) { - auto itemValue = node->GetItemValue(); - return itemValue; - } - if (node->GetNext().IsNull() == true) { - return ResultValue(); - } - auto nodeNew = node->GetNext(); - node = &nodeNew; - } - return ResultValue(); -} - -int JsonCommon::CheckLeafNode(JsonObject *node, std::vector &leafValue) -{ - if (node->GetChild().IsNull() == true) { - auto itemValue = node->GetItemValue(); - leafValue.emplace_back(itemValue); - } - if (node->GetChild().IsNull() != true) { - auto nodeNew = node->GetChild(); - CheckLeafNode(&nodeNew, leafValue); - } - if (node->GetNext().IsNull() != true) { - auto nodeNew = node->GetNext(); - CheckLeafNode(&nodeNew, leafValue); - } - return E_OK; -} - -std::vector JsonCommon::GetLeafValue(JsonObject *node) -{ - std::vector leafValue; - CheckLeafNode(node, leafValue); - return leafValue; -} - -bool JsonCommon::CheckNode(JsonObject *node, std::set filedSet, bool &errFlag) { - if (errFlag == false) { - return false; - } - std::string fieldName; - if (node->GetItemValue().GetValueType() != ResultValue::ValueType::VALUE_NULL) { - fieldName = node->GetItemFiled(); - if (filedSet.find(fieldName) == filedSet.end()) { - filedSet.insert(fieldName); - } - else { - errFlag = false; - return false; - } - for (int i = 0; i < fieldName.size(); i++) { - if (!(('a'<=fieldName[i] && fieldName[i]<='z')|| ('A'<=fieldName[i] && fieldName[i]<='Z') || ('0'<=fieldName[i] && fieldName[i]<='9') || '_' == fieldName[i])) { - errFlag = false; - return false; - } - } - } - if (node->GetChild().IsNull() != true) { - auto nodeNew = node->GetChild(); - std::set newFiledSet; - CheckNode(&nodeNew, newFiledSet, errFlag); - } - if (node->GetNext().IsNull() != true) { - auto nodeNew = node->GetNext(); - CheckNode(&nodeNew, filedSet, errFlag); - } - return errFlag; -} - -bool JsonCommon::CheckJsonField(const std::string &data) { - int errCode = E_OK; - JsonObject jsonObj = JsonObject::Parse(data, errCode); - if (errCode != E_OK) { - return false; - } - std::set filedSet; - bool errFlag = true; - return CheckNode(&jsonObj, filedSet, errFlag); -} - -int JsonCommon::ParseNode(JsonObject* node, std::vector singlePath, std::vector> &resultPath, bool isFirstFloor) -{ - std::vector fatherPath; - if (isFirstFloor) { - std::string tempParseName; - std::vector allFiledsName; - std::string priFieldName = node->GetItemFiled(); - for (int j = 0; j < priFieldName.size(); j++) { - if (priFieldName[j] != '.') { - tempParseName = tempParseName + priFieldName[j]; - } - if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { - allFiledsName.emplace_back(tempParseName); - tempParseName.clear(); - } - } - fatherPath = singlePath; - singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); - } else { - std::vector allFiledsName; - allFiledsName.emplace_back(node->GetItemFiled()); - fatherPath = singlePath; - singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); - } - if (node->GetChild().IsNull() != true && node->GetChild().GetItemFiled() != "") { - auto nodeNew = node->GetChild(); - ParseNode(&nodeNew, singlePath, resultPath, false); - } - else { - resultPath.emplace_back(singlePath); - } - if (node->GetNext().IsNull() != true) { - auto nodeNew = node->GetNext(); - ParseNode(&nodeNew, fatherPath, resultPath, isFirstFloor); - } - return 0; -} - -std::vector> JsonCommon::ParsePath(const JsonObject* const root) -{ - std::vector> resultPath; - auto projectionJson = root->GetChild(); - if (projectionJson.IsNull() == true) { - GLOGE("projectionJson is null"); - } - std::vector singlePath; - ParseNode(&projectionJson, singlePath, resultPath, true); - return resultPath; -} - -namespace { -JsonFieldPath ExpendPath(const JsonFieldPath &path, bool &isCollapse) -{ - if (path.size() > 1) { // only first lever has collapse field - return path; - } - JsonFieldPath splitPath; - const std::string &str = path[0]; - size_t start = 0; - size_t end = 0; - while ((end = str.find('.', start)) != std::string::npos) { - splitPath.push_back(str.substr(start, end - start)); - start = end + 1; - } - if (start < str.length()) { - splitPath.push_back(str.substr(start)); - } - isCollapse = (splitPath.size() > 1); - return splitPath; -} - -void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, - std::function foo) -{ - JsonObject child = obj.GetChild(); - while(!child.IsNull()) { - JsonFieldPath childPath = path; - childPath.push_back(child.GetItemFiled()); - if (foo != nullptr && foo(childPath, obj, child)) { - JsonObjectIterator(child, childPath, foo); - } - child = child.GetNext(); - } - return; -} -} - -int JsonCommon::Append(const JsonObject &src, const JsonObject &add) -{ - int externErrCode = E_OK; - JsonObjectIterator(add, {}, - [&src, &externErrCode](const JsonFieldPath &path, const JsonObject &father, const JsonObject &item) { - bool isCollapse = false; - JsonFieldPath itemPath = ExpendPath(path, isCollapse); - JsonFieldPath fatherPath = itemPath; - fatherPath.pop_back(); - int errCode = E_OK; - if (src.IsFieldExists(itemPath)) { - JsonObject srcItem = src.FindItem(itemPath, errCode); - if (errCode != E_OK) { - externErrCode = (externErrCode == E_OK ? errCode : externErrCode); - GLOGE("Find item in source json object failed. %d", errCode); - return false; - } - if (srcItem.GetType() == JsonObject::Type::JSON_LEAF && item.GetType() == JsonObject::Type::JSON_LEAF) { - srcItem.SetItemValue(item.GetItemValue()); - return false; // Both leaf node, no need iterate - } else if (srcItem.GetType() != item.GetType()) { - JsonObject srcFatherItem = src.FindItem(fatherPath, errCode); - if (errCode != E_OK) { - externErrCode = (externErrCode == E_OK ? errCode : externErrCode); - GLOGE("Find father item in source json object failed. %d", errCode); - return false; - } - srcFatherItem.DeleteItemFromObject(itemPath.back()); - srcFatherItem.AddItemToObject(itemPath.back(), item); - return false; // Different node types, overwrite directly, skip child node - } - return true; // Both array or object - } else { - if (isCollapse == true) { - GLOGE("Add collapse item to object failed, path not exist."); - externErrCode = -E_DATA_CONFLICT; - return false; - } - JsonObject srcFatherItem = src.FindItem(fatherPath, errCode); - if (errCode == E_OK) { - errCode = srcFatherItem.AddItemToObject(itemPath.back(), item); - if (errCode != E_OK) { - externErrCode = (externErrCode == E_OK ? errCode : externErrCode); - GLOGE("Add item to object failed. %d", errCode); - return false; - } - } else { - externErrCode = -E_DATA_CONFLICT; - GLOGE("Find father item in source json object failed. %d", errCode); - } - return false; // Source path not exist, overwrite directly, skip child node - } - }); - return externErrCode; -} -} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp deleted file mode 100644 index 98b7031131e4c0706d89208885a9cea3b9b6dd72..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp +++ /dev/null @@ -1,141 +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. -*/ - -#include "document_store.h" - -#include "collection_option.h" -#include "doc_common.h" -#include "doc_errno.h" -#include "grd_base/grd_type_export.h" -#include "log_print.h" - -namespace DocumentDB { -DocumentStore::DocumentStore(KvStoreExecutor *executor) : executor_(executor) -{ -} - -DocumentStore::~DocumentStore() -{ - delete executor_; -} - -int DocumentStore::CreateCollection(const std::string &name, const std::string &option, int flags) -{ - std::string lowerCaseName; - int errCode = E_OK; - if (!CheckCommon::CheckCollectionName(name, lowerCaseName, errCode)) { - GLOGE("Check collection name invalid. %d", errCode); - return errCode; - } - - errCode = E_OK; - CollectionOption collOption = CollectionOption::ReadOption(option, errCode); - if (errCode != E_OK) { - GLOGE("Read collection option str failed. %d", errCode); - return errCode; - } - - if (flags != 0 && flags != CHK_EXIST_COLLECTION) { - GLOGE("Check flags invalid."); - return -E_INVALID_ARGS; - } - - std::lock_guard lock(dbMutex_); - bool ignoreExists = (flags != CHK_EXIST_COLLECTION); - errCode = executor_->CreateCollection(lowerCaseName, ignoreExists); - if (errCode != E_OK) { - GLOGE("Create collection failed. %d", errCode); - return errCode; - } - std::string oriOptStr; - errCode = executor_->GetCollectionOption(lowerCaseName, oriOptStr); - if (errCode == -E_NOT_FOUND) { - executor_->SetCollectionOption(lowerCaseName, collOption.ToString()); - errCode = E_OK; - } else { - CollectionOption oriOption = CollectionOption::ReadOption(oriOptStr, errCode); - if (collOption != oriOption) { - GLOGE("Create collection failed, option changed."); - return -E_INVALID_CONFIG_VALUE; - } - } - - return errCode; -} - -int DocumentStore::DropCollection(const std::string &name, int flags) -{ - std::string lowerCaseName; - int errCode = E_OK; - if (!CheckCommon::CheckCollectionName(name, lowerCaseName, errCode)) { - GLOGE("Check collection name invalid. %d", errCode); - return errCode; - } - - if (flags != 0 && flags != CHK_NON_EXIST_COLLECTION) { - GLOGE("Check flags invalid."); - return -E_INVALID_ARGS; - } - - bool ignoreNonExists = (flags != CHK_NON_EXIST_COLLECTION); - errCode = executor_->DropCollection(lowerCaseName, ignoreNonExists); - if (errCode != E_OK) { - GLOGE("Drop collection failed. %d", errCode); - return errCode; - } - - std::lock_guard lock(dbMutex_); - errCode = executor_->CleanCollectionOption(lowerCaseName); - if (errCode != E_OK) { - GLOGE("Clean collection option failed. %d", errCode); - } - - return errCode; -} - -int DocumentStore::UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, - int flag) -{ - return E_OK; -} - -int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, - int flags) -{ - std::string lowerCaseCollName; - int errCode = E_OK; - if (!CheckCommon::CheckCollectionName(collection, lowerCaseCollName, errCode)) { - GLOGE("Check collection name invalid. %d", errCode); - return errCode; - } - - // TODO:: check filter - - // TODO:: check document - - if (flags != GRD_DOC_APPEND && flags != GRD_DOC_REPLACE) { - GLOGE("Check flags invalid."); - return -E_INVALID_ARGS; - } - - auto coll = Collection(lowerCaseCollName, executor_); - - std::string docId(filter.begin(), filter.end()); - bool isReplace = (flags & GRD_DOC_REPLACE == GRD_DOC_REPLACE); - - std::lock_guard lock(dbMutex_); - return coll.UpsertDocument(docId, document, isReplace); -} -} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp deleted file mode 100644 index 98dfd182e740f21257426bf81345c1831efdebc2..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp +++ /dev/null @@ -1,244 +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. -*/ - -#include "doc_common.h" -#include "doc_errno.h" -#include "log_print.h" -#include "sqlite_utils.h" -#include "sqlite_store_executor_impl.h" - -namespace DocumentDB { -int SqliteStoreExecutor::CreateDatabase(const std::string &path, const DBConfig &config, sqlite3 *&db) -{ - if (db != nullptr) { - return -E_INVALID_ARGS; - } - - int errCode = SQLiteUtils::CreateDataBase(path, 0, db); - if (errCode != E_OK || db == nullptr) { - GLOGE("Open or create database failed. %d", errCode); - return errCode; - } - - std::string pageSizeSql = "PRAGMA page_size=" + std::to_string(config.GetPageSize() * 1024); - errCode = SQLiteUtils::ExecSql(db, pageSizeSql); - if (errCode != E_OK) { - GLOGE("Set db page size failed. %d", errCode); - goto END; - } - - errCode = SQLiteUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS grd_meta (key BLOB PRIMARY KEY, value BLOB);"); - if (errCode != E_OK) { - GLOGE("Create meta table failed. %d", errCode); - goto END; - } - - return E_OK; - -END: - sqlite3_close_v2(db); - db = nullptr; - return errCode; -} - -SqliteStoreExecutor::SqliteStoreExecutor(sqlite3 *handle) : dbHandle_(handle) -{ -} - -SqliteStoreExecutor::~SqliteStoreExecutor() -{ - sqlite3_close_v2(dbHandle_); - dbHandle_ = nullptr; -} - -int SqliteStoreExecutor::GetDBConfig(std::string &config) -{ - std::string dbConfigKeyStr = "DB_CONFIG"; - Key dbConfigKey = {dbConfigKeyStr.begin(), dbConfigKeyStr.end()}; - Value dbConfigVal; - int errCode = GetData("grd_meta", dbConfigKey, dbConfigVal); - config.assign(dbConfigVal.begin(), dbConfigVal.end()); - return errCode; -} - -int SqliteStoreExecutor::SetDBConfig(const std::string &config) -{ - std::string dbConfigKeyStr = "DB_CONFIG"; - Key dbConfigKey = {dbConfigKeyStr.begin(), dbConfigKeyStr.end()}; - Value dbConfigVal = {config.begin(), config.end()}; - return PutData("grd_meta", dbConfigKey, dbConfigVal); -} - -int SqliteStoreExecutor::PutData(const std::string &collName, const Key &key, const Value &value) -{ - if (dbHandle_ == nullptr) { - return -E_ERROR; - } - - std::string sql = "INSERT OR REPLACE INTO '" + collName + "' VALUES (?,?);"; - int errCode = SQLiteUtils::ExecSql(dbHandle_, sql, [key, value](sqlite3_stmt *stmt) { - SQLiteUtils::BindBlobToStatement(stmt, 1, key); - SQLiteUtils::BindBlobToStatement(stmt, 2, value); - return E_OK; - }, nullptr); - if (errCode != SQLITE_OK) { - GLOGE("[sqlite executor] Put data failed. err=%d", errCode); - return errCode; - } - return E_OK; -} - -int SqliteStoreExecutor::GetData(const std::string &collName, const Key &key, Value &value) const -{ - if (dbHandle_ == nullptr) { - GLOGE("Invalid db handle."); - return -E_ERROR; - } - int innerErrorCode = -E_NOT_FOUND; - std::string sql = "SELECT value FROM '" + collName + "' WHERE key=?;"; - int errCode = SQLiteUtils::ExecSql(dbHandle_, sql, [key](sqlite3_stmt *stmt) { - SQLiteUtils::BindBlobToStatement(stmt, 1, key); - return E_OK; - }, [&value, &innerErrorCode](sqlite3_stmt *stmt) { - SQLiteUtils::GetColumnBlobValue(stmt, 0, value); - innerErrorCode = E_OK; - return E_OK; - }); - if (errCode != SQLITE_OK) { - GLOGE("[sqlite executor] Get data failed. err=%d", errCode); - return errCode; - } - return innerErrorCode; -} - -int SqliteStoreExecutor::DelData(const std::string &collName, const Key &key) -{ - if (dbHandle_ == nullptr) { - GLOGE("Invalid db handle."); - return -E_ERROR; - } - - std::string sql = "DELETE FROM '" + collName + "' WHERE key=?;"; - int errCode = SQLiteUtils::ExecSql(dbHandle_, sql, [key](sqlite3_stmt *stmt) { - SQLiteUtils::BindBlobToStatement(stmt, 1, key); - return E_OK; - }, nullptr); - - if (errCode != SQLITE_OK) { - GLOGE("[sqlite executor] Delete data failed. err=%d", errCode); - } - return errCode; -} - -int SqliteStoreExecutor::CreateCollection(const std::string &name, bool ignoreExists) -{ - if (dbHandle_ == nullptr) { - return -E_ERROR; - } - std::string collName = COLL_PREFIX + name; - if (!ignoreExists) { - int errCode = E_OK; - bool isExists = IsCollectionExists(collName, errCode); - if (errCode != E_OK) { - return errCode; - } - if (isExists) { - GLOGE("[sqlite executor] Create collectoin failed, collection already exists."); - return -E_COLLECTION_CONFLICT; - } - } - - std::string sql = "CREATE TABLE IF NOT EXISTS '" + collName + "' (key BLOB PRIMARY KEY, value BLOB);"; - int errCode = SQLiteUtils::ExecSql(dbHandle_, sql); - if (errCode != SQLITE_OK) { - GLOGE("[sqlite executor] Create collectoin failed. err=%d", errCode); - return errCode; - } - return E_OK; -} - -int SqliteStoreExecutor::DropCollection(const std::string &name, bool ignoreNonExists) -{ - if (dbHandle_ == nullptr) { - return -E_ERROR; - } - - std::string collName = COLL_PREFIX + name; - if (!ignoreNonExists) { - int errCode = E_OK; - bool isExists = IsCollectionExists(collName, errCode); - if (errCode != E_OK) { - return errCode; - } - if (!isExists) { - GLOGE("[sqlite executor] Drop collectoin failed, collection not exists."); - return -E_NO_DATA; - } - } - - std::string sql = "DROP TABLE IF EXISTS '" + collName + "';"; - int errCode = SQLiteUtils::ExecSql(dbHandle_, sql); - if (errCode != SQLITE_OK) { - GLOGE("[sqlite executor] Drop collectoin failed. err=%d", errCode); - return errCode; - } - return E_OK; -} - -bool SqliteStoreExecutor::IsCollectionExists(const std::string &name, int &errCode) -{ - bool isExists = false; - std::string sql = "SELECT tbl_name FROM sqlite_master WHERE tbl_name=?;"; - - errCode = SQLiteUtils::ExecSql(dbHandle_, sql, [name](sqlite3_stmt *stmt) { - SQLiteUtils::BindTextToStatement(stmt, 1, name); - return E_OK; - }, [&isExists](sqlite3_stmt *stmt) { - isExists = true; - return E_OK; - }); - - if (errCode != E_OK) { - GLOGE("Check collection exist failed. %d", errCode); - } - - return isExists; -} - -int SqliteStoreExecutor::GetCollectionOption(const std::string &name, std::string &option) -{ - std::string collOptKeyStr = "COLLECTION_OPTION_" + name; - Key collOptKey = {collOptKeyStr.begin(), collOptKeyStr.end()}; - Value collOptVal; - int errCode = GetData("grd_meta", collOptKey, collOptVal); - option.assign(collOptVal.begin(), collOptVal.end()); - return errCode; -} - -int SqliteStoreExecutor::SetCollectionOption(const std::string &name, const std::string &option) -{ - std::string collOptKeyStr = "COLLECTION_OPTION_" + name; - Key collOptKey = {collOptKeyStr.begin(), collOptKeyStr.end()}; - Value collOptVal = {option.begin(), option.end()}; - return PutData("grd_meta", collOptKey, collOptVal); -} - -int SqliteStoreExecutor::CleanCollectionOption(const std::string &name) -{ - std::string collOptKeyStr = "COLLECTION_OPTION_" + name; - Key collOptKey = {collOptKeyStr.begin(), collOptKeyStr.end()}; - return DelData("grd_meta", collOptKey); -} -} // DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_data_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_data_test.cpp deleted file mode 100644 index 6f61aac7140255144b53f867dd924d534b5a4168..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_data_test.cpp +++ /dev/null @@ -1,195 +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. -*/ - -#include - -#include "doc_errno.h" -#include "documentdb_test_utils.h" -#include "log_print.h" -#include "grd_base/grd_db_api.h" -#include "grd_base/grd_error.h" -#include "grd_document/grd_document_api.h" -#include "sqlite_utils.h" - -using namespace DocumentDB; -using namespace testing::ext; -using namespace DocumentDBUnitTest; - -namespace { -std::string g_path = "./document.db"; -GRD_DB *g_db = nullptr; -const char *g_coll = "student"; -} - -class DocumentDBDataTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -void DocumentDBDataTest::SetUpTestCase(void) -{ -} - -void DocumentDBDataTest::TearDownTestCase(void) -{ -} - -void DocumentDBDataTest::SetUp(void) -{ - EXPECT_EQ(GRD_DBOpen(g_path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &g_db), GRD_OK); - EXPECT_NE(g_db, nullptr); - - EXPECT_EQ(GRD_CreateCollection(g_db, g_coll, "", 0), GRD_OK); -} - -void DocumentDBDataTest::TearDown(void) -{ - if (g_db != nullptr) { - EXPECT_EQ(GRD_DBClose(g_db, GRD_DB_CLOSE), GRD_OK); - g_db = nullptr; - } - DocumentDBTestUtils::RemoveTestDbFiles(g_path); -} - -/** - * @tc.name: UpsertDataTest001 - * @tc.desc: Test upsert data into collection - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest001, TestSize.Level0) -{ - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, "1234", document.c_str(), GRD_DOC_REPLACE), GRD_OK); -} - -/** - * @tc.name: UpsertDataTest002 - * @tc.desc: Test upsert data with db is nullptr - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest002, TestSize.Level0) -{ - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - EXPECT_EQ(GRD_UpSertDoc(nullptr, g_coll, "1234", document.c_str(), GRD_DOC_REPLACE), GRD_INVALID_ARGS); -} - -/** - * @tc.name: UpsertDataTest003 - * @tc.desc: Test upsert data with invalid collection name - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest003, TestSize.Level0) -{ - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - std::vector invalidName = { - nullptr, - "", - "GRD_123", - "grd_123", - "GM_SYS_123", - "gm_sys_123", - }; - for (auto name : invalidName) { - GLOGD("UpsertDataTest003: upsert data with collectionname: %s", name); - EXPECT_EQ(GRD_UpSertDoc(g_db, name, "1234", document.c_str(), GRD_DOC_REPLACE), GRD_INVALID_ARGS); - } -} - -HWTEST_F(DocumentDBDataTest, UpsertDataTest004, TestSize.Level0) -{ - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - std::vector invalidFilter = { - nullptr, - "", - R""({"name":"Tmono"})"", - R""({"value":{"_id":"1234"}})"", - R""({"_id":1234})"", - }; - for (auto filter : invalidFilter) { - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, filter, document.c_str(), GRD_DOC_REPLACE), GRD_INVALID_ARGS); - } -} - -HWTEST_F(DocumentDBDataTest, UpsertDataTest005, TestSize.Level0) -{ - std::string filter = R""({"_id":1234})""; - std::vector invalidDocument = { - nullptr, - "", - "GRD_123", - "grd_123", - "GM_SYS_123", - "gm_sys_123", - }; - for (auto document : invalidDocument) { - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, filter.c_str(), document, GRD_DOC_REPLACE), GRD_INVALID_FORMAT); - } -} - -/** - * @tc.name: UpsertDataTest006 - * @tc.desc: Test upsert data with invalid flags - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest006, TestSize.Level0) -{ - std::string filter = R""({"_id":1234})""; - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - - for (auto flags : std::vector {2, 4, 8, 64, 1024, UINT32_MAX}) { - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, filter.c_str(), document.c_str(), flags), GRD_INVALID_ARGS); - } -} - -/** - * @tc.name: UpsertDataTest007 - * @tc.desc: Test upsert data with collection not create - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest007, TestSize.Level0) -{ - std::string val = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - EXPECT_EQ(GRD_UpSertDoc(g_db, "collection_not_exists", "1234", val.c_str(), GRD_DOC_REPLACE), GRD_NO_DATA); -} - -/** - * @tc.name: UpsertDataTest008 - * @tc.desc: Test upsert data with different document in append - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpsertDataTest008, TestSize.Level0) -{ - std::string filter = R""({"_id":1234})""; - std::string document = R""({"name":"Tmn","age":18,"addr":{"city":"shanghai","postal":200001}})""; - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_REPLACE), GRD_OK); - - std::string updateDoc = R""({"name":"Xue","case":2,"age":28,"addr":{"city":"shenzhen","postal":518000}})""; - EXPECT_EQ(GRD_UpSertDoc(g_db, g_coll, filter.c_str(), updateDoc.c_str(), GRD_DOC_APPEND), GRD_OK); -} \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/idata_share_service.h b/services/distributeddataservice/service/data_share/idata_share_service.h index 87573705c74cea9d2363d5e40af234b3db423701..6d465247baef0b92489fce5ef7baf2f5554ac850 100644 --- a/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/services/distributeddataservice/service/data_share/idata_share_service.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 @@ -22,6 +22,8 @@ #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" +#include "datashare_template.h" +#include "data_proxy_observer.h" namespace OHOS::DataShare { class IDataShareService { @@ -31,6 +33,18 @@ public: DATA_SHARE_SERVICE_CMD_DELETE, DATA_SHARE_SERVICE_CMD_UPDATE, DATA_SHARE_SERVICE_CMD_QUERY, + DATA_SHARE_SERVICE_CMD_ADD_TEMPLATE, + DATA_SHARE_SERVICE_CMD_DEL_TEMPLATE, + DATA_SHARE_SERVICE_CMD_PUBLISH, + DATA_SHARE_SERVICE_CMD_GET_DATA, + DATA_SHARE_SERVICE_CMD_SUBSCRIBE_RDB, + DATA_SHARE_SERVICE_CMD_UNSUBSCRIBE_RDB, + DATA_SHARE_SERVICE_CMD_ENABLE_SUBSCRIBE_RDB, + DATA_SHARE_SERVICE_CMD_DISABLE_SUBSCRIBE_RDB, + DATA_SHARE_SERVICE_CMD_SUBSCRIBE_PUBLISHED, + DATA_SHARE_SERVICE_CMD_UNSUBSCRIBE_PUBLISHED, + DATA_SHARE_SERVICE_CMD_ENABLE_SUBSCRIBE_PUBLISHED, + DATA_SHARE_SERVICE_CMD_DISABLE_SUBSCRIBE_PUBLISHED, DATA_SHARE_SERVICE_CMD_MAX }; @@ -43,6 +57,26 @@ public: virtual int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) = 0; virtual std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; + virtual int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) = 0; + virtual int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) = 0; + virtual std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) = 0; + virtual Data GetData(const std::string &bundleNameOfProvider) = 0; + virtual std::vector SubscribeRdbData( + const std::vector &uris, const TemplateId &id, const sptr observer) = 0; + virtual std::vector UnsubscribeRdbData( + const std::vector &uris, const TemplateId &id) = 0; + virtual std::vector EnableRdbSubs( + const std::vector &uris, const TemplateId &id) = 0; + virtual std::vector DisableRdbSubs( + const std::vector &uris, const TemplateId &id) = 0; + virtual std::vector SubscribePublishedData(const std::vector &uris, + const int64_t subscriberId, const sptr observer) = 0; + virtual std::vector UnsubscribePublishedData(const std::vector &uris, + const int64_t subscriberId) = 0; + virtual std::vector EnablePubSubs(const std::vector &uris, + const int64_t subscriberId) = 0; + virtual std::vector DisablePubSubs(const std::vector &uris, + const int64_t subscriberId) = 0; }; } // namespace OHOS::DataShare #endif diff --git a/services/distributeddataservice/service/data_share/permission_proxy.cpp b/services/distributeddataservice/service/data_share/permission_proxy.cpp deleted file mode 100644 index 91ea2b973b78e65b7bcf825077af05f6594a488c..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/data_share/permission_proxy.cpp +++ /dev/null @@ -1,152 +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. - */ -#define LOG_TAG "PermissionProxy" -#include "permission_proxy.h" - -#include "accesstoken_kit.h" -#include "account/account_delegate.h" -#include "bundle_info.h" -#include "bundle_mgr_proxy.h" -#include "device_manager_adapter.h" -#include "log_print.h" -#include "metadata/appid_meta_data.h" -#include "metadata/meta_data_manager.h" -#include "utils/anonymous.h" - -namespace OHOS::DataShare { -BundleMgrProxy PermissionProxy::bmsProxy_; -bool PermissionProxy::GetBundleInfo(const std::string &bundleName, uint32_t tokenId, - AppExecFwk::BundleInfo &bundleInfo) -{ - if (!bmsProxy_.GetBundleInfoFromBMS(bundleName, tokenId, bundleInfo)) { - ZLOGE("GetBundleInfoFromBMS failed!"); - return false; - } - return true; -} - -PermissionProxy::PermissionState PermissionProxy::QueryWritePermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo) -{ - for (auto &item : bundleInfo.extensionInfos) { - if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - permission = item.writePermission; - if (permission.empty()) { - ZLOGW("WritePermission is empty! BundleName is %{public}s, tokenId is %{public}x", - bundleInfo.name.c_str(), tokenId); - return PermissionState::NOT_FIND; - } - int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); - if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { - ZLOGE("Verify write permission denied!"); - return PermissionState::DENIED; - } - return PermissionState::GRANTED; - } - } - return PermissionState::DENIED; -} - -PermissionProxy::PermissionState PermissionProxy::QueryReadPermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo) -{ - for (auto &item : bundleInfo.extensionInfos) { - if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { - if (item.readPermission.empty()) { - ZLOGW("ReadPermission is empty! BundleName is %{public}s, tokenId is %{public}x", - bundleInfo.name.c_str(), tokenId); - return PermissionState::NOT_FIND; - } - int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission); - if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { - ZLOGE("Verify Read permission denied!"); - return PermissionState::DENIED; - } - return PermissionState::GRANTED; - } - } - return PermissionState::DENIED; -} - -std::string PermissionProxy::GetTableNameByCrossUserMode(const ProfileInfo &profileInfo, - int32_t userId, bool isSingleApp, const UriInfo &uriInfo) -{ - std::string tableName = uriInfo.tableName; - if (!isSingleApp) { - return tableName; - } - - AccessSystemMode crossUserMode = GetCrossUserMode(profileInfo, uriInfo); - if (crossUserMode == AccessSystemMode::UNIQUE) { - ZLOGD("hap in unique mode, bundleName is %{public}s, userId is %{public}d", - uriInfo.bundleName.c_str(), userId); - return tableName.append("_").append(std::to_string(userId)); - } - return tableName; -} - -PermissionProxy::AccessSystemMode PermissionProxy::GetCrossUserMode(const ProfileInfo &profileInfo, - const UriInfo &uriInfo) -{ - AccessSystemMode crossUserMode = AccessSystemMode::UNDEFINED; - for (auto &item : profileInfo.tableConfig) { - UriInfo temp; - AccessSystemMode curUserMode = static_cast(item.crossUserMode); - if (curUserMode == AccessSystemMode::UNDEFINED) { - continue; - } - if (item.uri == "*") { - crossUserMode = crossUserMode == AccessSystemMode::UNDEFINED ? curUserMode : crossUserMode; - continue; - } - if (!URIUtils::GetInfoFromURI(item.uri, temp, true)) { - ZLOGE("GetInfoFromURI failed, uri is %{public}s", DistributedData::Anonymous::Change(item.uri).c_str()); - continue; - } - if (temp.storeName != uriInfo.storeName) { - continue; - } - if (temp.tableName.empty()) { - crossUserMode = curUserMode; - continue; - } - if (temp.tableName == uriInfo.tableName) { - return curUserMode; - } - } - return crossUserMode; -} - -void PermissionProxy::FillData(DistributedData::StoreMetaData &meta, int32_t userId) -{ - meta.deviceId = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; - meta.user = std::to_string(userId); -} - -bool PermissionProxy::QueryMetaData(const std::string &bundleName, const std::string &storeName, - DistributedData::StoreMetaData &metaData, int32_t userId) -{ - DistributedData::StoreMetaData meta; - FillData(meta, userId); - meta.bundleName = bundleName; - meta.storeId = storeName; - bool isCreated = DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), metaData); - if (!isCreated) { - ZLOGE("Interface token is not equal"); - return false; - } - return true; -} -} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2ad30b5cbfc5b0055c5f107008890ef310f5289 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp @@ -0,0 +1,87 @@ +/* + * 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 "LoadConfigFromDataProxyNodeStrategy" + +#include "load_config_from_data_proxy_node_strategy.h" + +#include "bundle_mgr_proxy.h" +#include "common/uri_utils.h" +#include "datashare_errno.h" +#include "log_print.h" + +namespace OHOS::DataShare { +bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr context) +{ + if (!LoadConfigFromUri(context)) { + return false; + } + context->type = DataProperties::PUBLISHED_DATA_TYPE; + if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + context->calledBundleName, context->currentUserId, context->bundleInfo)) { + ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str()); + return false; + } + for (auto &hapModuleInfo : context->bundleInfo.hapModuleInfos) { + auto proxyDatas = hapModuleInfo.proxyDatas; + for (auto &proxyData : proxyDatas) { + if (proxyData.uri != context->uri) { + continue; + } + context->permission = context->isRead ? proxyData.requiredReadPermission + : proxyData.requiredWritePermission; + if (context->permission.empty()) { + context->permission = "reject"; + } + DataProperties properties; + bool isCompressed = !hapModuleInfo.hapPath.empty(); + std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath; + if (!DataShareProfileInfo::GetDataPropertiesFromProxyDatas( + proxyData, resourcePath, isCompressed, properties)) { + return true; + } + GetContextInfoFromDataProperties(properties, hapModuleInfo.moduleName, context); + return true; + } + } + if (context->callerBundleName == context->calledBundleName) { + ZLOGI("access private data, caller and called is same, go"); + return true; + } + context->errCode = E_URI_NOT_EXIST; + ZLOGI("not find DataProperties! %{private}s is private", context->uri.c_str()); + return false; +} + +bool LoadConfigFromDataProxyNodeStrategy::GetContextInfoFromDataProperties(const DataProperties &properties, + const std::string &moduleName, std::shared_ptr context) +{ + if (properties.scope == DataProperties::MODULE_SCOPE) { + // module scope + context->calledModuleName = moduleName; + } + context->calledStoreName = properties.storeName; + context->calledTableName = properties.tableName; + context->type = properties.type; + return true; +} + +bool LoadConfigFromDataProxyNodeStrategy::LoadConfigFromUri(std::shared_ptr context) +{ + if (!URIUtils::GetBundleNameFromProxyURI(context->uri, context->calledBundleName)) { + return false; + } + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/permission_proxy.h b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.h similarity index 31% rename from services/distributeddataservice/service/data_share/permission_proxy.h rename to services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.h index 1d17f32120e6d8a937310d60b13382dd8cbaa3f1..802bc214409ce50f43ad9b6b99e88246ff9541ae 100644 --- a/services/distributeddataservice/service/data_share/permission_proxy.h +++ b/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.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 @@ -13,45 +13,28 @@ * limitations under the License. */ -#ifndef DATASHARESERVICE_PERMISSION_PROXY_H -#define DATASHARESERVICE_PERMISSION_PROXY_H +#ifndef DATASHARESERVICE_LOAD_CONFIG_FROM_DATA_PROXY_NODE_STRAGETY_H +#define DATASHARESERVICE_LOAD_CONFIG_FROM_DATA_PROXY_NODE_STRAGETY_H -#include - -#include "bundle_info.h" -#include "bundle_mgr_proxy.h" #include "data_share_profile_info.h" -#include "metadata/store_meta_data.h" +#include "strategy.h" namespace OHOS::DataShare { -class PermissionProxy { +using namespace OHOS::RdbBMSAdapter; +class LoadConfigFromDataProxyNodeStrategy final : public Strategy { public: - enum class AccessSystemMode { - UNDEFINED = 0, - SHARED, - UNIQUE, - }; - - enum class PermissionState { - DENIED = -1, - NOT_FIND = 0, - GRANTED, - }; - - static bool GetBundleInfo(const std::string &bundleName, uint32_t tokenId, AppExecFwk::BundleInfo &bundleInfo); - static PermissionState QueryWritePermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo); - static PermissionState QueryReadPermission(uint32_t tokenId, - std::string &permission, const AppExecFwk::BundleInfo &bundleInfo); - static bool QueryMetaData(const std::string &bundleName, const std::string &storeName, - DistributedData::StoreMetaData &metaData, int32_t userId); - static std::string GetTableNameByCrossUserMode(const ProfileInfo &profileInfo, - int32_t userId, bool isSingleApp, const UriInfo &uriInfo); + LoadConfigFromDataProxyNodeStrategy() = default; + bool operator()(std::shared_ptr context) override; private: - static void FillData(DistributedData::StoreMetaData &data, int32_t userId); - static AccessSystemMode GetCrossUserMode(const ProfileInfo &profileInfo, const UriInfo &uriInfo); - static BundleMgrProxy bmsProxy_; + enum class PATH_PARAMS : int32_t { + STORE_NAME = 0, + TABLE_NAME, + PARAM_SIZE + }; + bool LoadConfigFromUri(std::shared_ptr context); + bool GetContextInfoFromDataProperties( + const DataProperties &properties, const std::string &moduleName, std::shared_ptr context); }; } // namespace OHOS::DataShare -#endif // DATASHARESERVICE_PERMISSION_PROXY_H \ No newline at end of file +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5df4f1bbce2295c8e10c75c592063c1299c262b5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp @@ -0,0 +1,117 @@ +/* + * 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 "LoadConfigFromDataShareBundleInfoStrategy" + +#include "load_config_from_data_share_bundle_info_strategy.h" + +#include "bundle_mgr_proxy.h" +#include "log_print.h" +#include "uri_utils.h" + +namespace OHOS::DataShare { +struct ConfigData { + constexpr static int8_t TABLE_MATCH_PRIORITY = 3; + constexpr static int8_t STORE_MATCH_PRIORITY = 2; + constexpr static int8_t COMMON_MATCH_PRIORITY = 1; + constexpr static int8_t UNDEFINED_PRIORITY = -1; + ConfigData() : crossMode_(AccessSystemMode::UNDEFINED, UNDEFINED_PRIORITY) {} + void SetCrossUserMode(uint8_t priority, uint8_t crossMode) + { + if (crossMode_.second < priority && crossMode > AccessSystemMode::UNDEFINED && + crossMode < AccessSystemMode::MAX) { + crossMode_.first = static_cast(crossMode); + crossMode_.second = priority; + } + } + void FillIntoContext(std::shared_ptr context) + { + if (crossMode_.second != ConfigData::UNDEFINED_PRIORITY) { + context->accessSystemMode = crossMode_.first; + } + } + +private: + std::pair crossMode_; +}; + +bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromProfile( + const ProfileInfo &profileInfo, std::shared_ptr context) +{ + std::string storeUri = URIUtils::DATA_SHARE_SCHEMA + context->calledBundleName + "/" + context->calledModuleName + + "/" + context->calledStoreName; + std::string tableUri = storeUri + "/" + context->calledTableName; + ConfigData result; + for (auto &item : profileInfo.tableConfig) { + if (item.uri == tableUri) { + result.SetCrossUserMode(ConfigData::TABLE_MATCH_PRIORITY, item.crossUserMode); + continue; + } + if (item.uri == storeUri) { + result.SetCrossUserMode(ConfigData::STORE_MATCH_PRIORITY, item.crossUserMode); + continue; + } + if (item.uri == "*") { + result.SetCrossUserMode(ConfigData::COMMON_MATCH_PRIORITY, item.crossUserMode); + continue; + } + } + result.FillIntoContext(context); + return true; +} + +bool LoadConfigFromDataShareBundleInfoStrategy::operator()(std::shared_ptr context) +{ + if (!LoadConfigFromUri(context)) { + ZLOGE("LoadConfigFromUri failed! bundleName: %{public}s", context->calledBundleName.c_str()); + return false; + } + if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + context->calledBundleName, context->currentUserId, context->bundleInfo)) { + ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str()); + return false; + } + for (auto &item : context->bundleInfo.extensionInfos) { + if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { + context->permission = context->isRead ? item.readPermission : item.writePermission; + + std::vector infos; + auto ret = DataShareProfileInfo::GetResConfigFile(item, infos); + if (!ret) { + return true; // optional meta data config + } + ProfileInfo profileInfo; + if (!profileInfo.Unmarshall(infos[0])) { + ZLOGE("parse failed! %{public}s", infos[0].c_str()); + return false; + } + LoadConfigFromProfile(profileInfo, context); + return true; + } + } + return false; +} +bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromUri(std::shared_ptr context) +{ + UriInfo uriInfo; + if (!URIUtils::GetInfoFromURI(context->uri, uriInfo)) { + return false; + } + context->calledBundleName = std::move(uriInfo.bundleName); + context->calledModuleName = std::move(uriInfo.moduleName); + context->calledStoreName = std::move(uriInfo.storeName); + context->calledTableName = std::move(uriInfo.tableName); + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.h b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..4b62a6f5267a630e2dc4be9a7d13828b3d701798 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.h @@ -0,0 +1,33 @@ +/* + * 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 DATASHARESERVICE_LOAD_CONFIG_FROM_DATA_SHARE_BUNDLE_INFO_STRAGETY_H +#define DATASHARESERVICE_LOAD_CONFIG_FROM_DATA_SHARE_BUNDLE_INFO_STRAGETY_H + +#include "data_share_profile_info.h" +#include "strategy.h" +namespace OHOS::DataShare { +using namespace OHOS::RdbBMSAdapter; +class LoadConfigFromDataShareBundleInfoStrategy final: public Strategy { +public: + LoadConfigFromDataShareBundleInfoStrategy() = default; + bool operator()(std::shared_ptr context) override; + +private: + bool LoadConfigFromProfile(const ProfileInfo &profileInfo, std::shared_ptr context); + bool LoadConfigFromUri(std::shared_ptr context); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1fc64494edc4d44944d26e69dfc0d3b3ec640bce --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/delete_strategy.cpp @@ -0,0 +1,71 @@ +/* + * 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 "DeleteStrategy" + +#include "delete_strategy.h" + +#include "db_delegate.h" +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/load_config_from_bundle_info_strategy.h" +#include "general/permission_strategy.h" +#include "general/process_single_app_user_cross_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +int64_t DeleteStrategy::Execute(std::shared_ptr context, const DataSharePredicates &predicate) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return -1; + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return -1; + } + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + if (delegate == nullptr) { + ZLOGE("Create fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); + return -1; + } + return delegate->Delete(context->calledTableName, predicate); +} +Strategy *DeleteStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromBundleInfoStrategy(), + new (std::nothrow)PermissionStrategy(), + new (std::nothrow)LoadConfigDataInfoStrategy(), + new (std::nothrow)ProcessSingleAppUserCrossStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/delete_strategy.h b/services/distributeddataservice/service/data_share/strategies/delete_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..08e98e3f6a928ffefb2a4f79e0d8900a30418b57 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/delete_strategy.h @@ -0,0 +1,33 @@ +/* + * 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 DATASHARESERVICE_DELETE_STRAGETY_H +#define DATASHARESERVICE_DELETE_STRAGETY_H + +#include + +#include "datashare_predicates.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class DeleteStrategy final { +public: + static int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6842ed8bb71f5fb0ebe57161196e3948276055ba --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.cpp @@ -0,0 +1,24 @@ +/* + * 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_is_data_proxy_strategy.h" + +#include "uri_utils.h" + +namespace OHOS::DataShare { +bool CheckIsDataProxyStrategy::operator()(std::shared_ptr context) +{ + return URIUtils::IsDataProxyURI(context->uri); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..35da76719e0ed0dc291c135ab1a3d170e524420b --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/check_is_data_proxy_strategy.h @@ -0,0 +1,26 @@ +/* + * 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 DATASHARESERVICE_CHECK_IS_DATA_PROXY_STRAGETY_H +#define DATASHARESERVICE_CHECK_IS_DATA_PROXY_STRAGETY_H + +#include "strategy.h" +namespace OHOS::DataShare { +class CheckIsDataProxyStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76da4f48d2bf49a751ef76e59a6b774c571e103d --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.cpp @@ -0,0 +1,25 @@ +/* + * 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 "CheckIsSystemAppStrategy" + +#include "check_is_single_app_strategy.h" +#include "log_print.h" + +namespace OHOS::DataShare { +bool CheckIsSingleAppStrategy::operator()(std::shared_ptr context) +{ + return context->bundleInfo.singleton; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..4fa66f46fd2c6ea4b7abe669693ded368878aa8a --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/check_is_single_app_strategy.h @@ -0,0 +1,26 @@ +/* + * 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 DATASHARESERVICE_CHECK_IS_SYSTEM_APP_STRAGETY_H +#define DATASHARESERVICE_CHECK_IS_SYSTEM_APP_STRAGETY_H + +#include "strategy.h" +namespace OHOS::DataShare { +class CheckIsSingleAppStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eecd0c38089df7b3c6689e9f05069c71d9ec5278 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.cpp @@ -0,0 +1,84 @@ +/* + * 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 "ConnectExtensionStrategy" + +#include "connect_extension_strategy.h" + +#include +#include "log_print.h" +#include "callback_impl.h" + +namespace OHOS::DataShare { +bool ConnectExtensionStrategy::operator()(std::shared_ptr context) +{ + for (auto &extension: context->bundleInfo.extensionInfos) { + if (extension.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { + return Connect(context); + } + } + return false; +} + +ConnectExtensionStrategy::ConnectExtensionStrategy() : data_(1) {} + +bool ConnectExtensionStrategy::Connect(std::shared_ptr context) +{ + std::lock_guard lock(mutex_); + AAFwk::Want want; + want.SetUri(context->uri); + data_.Clear(); + sptr callback = new CallbackImpl(data_); + ZLOGI("Start connect %{public}s", context->uri.c_str()); + ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, callback, nullptr); + if (ret != ERR_OK) { + ZLOGE("connect ability failed, ret = %{public}d", ret); + return false; + } + bool result = data_.GetValue(); + if (result) { + ZLOGI("connect ability ended successfully"); + } + data_.Clear(); + AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(callback); + if (!data_.GetValue()) { + ZLOGI("disconnect ability ended successfully"); + } + return result; +} + +bool ConnectExtensionStrategy::Execute( + std::shared_ptr context, std::function isFinished, int maxWaitTimeMs) +{ + ConnectExtensionStrategy strategy; + if (!strategy(context)) { + return false; + } + if (isFinished == nullptr) { + return true; + } + int waitTime = 0; + static constexpr int retryTime = 500; + while (!isFinished()) { + if (waitTime > maxWaitTimeMs) { + ZLOGE("cannot finish work"); + return false; + } + ZLOGI("has wait %{public}d ms", waitTime); + std::this_thread::sleep_for(std::chrono::milliseconds(retryTime)); + waitTime += retryTime; + } + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..57d76c48e5d5f8bb6414887a3bbdd2de7259cfed --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/connect_extension_strategy.h @@ -0,0 +1,33 @@ +/* + * 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 DATASHARESERVICE_CONNECT_EXTENSION_STRAGETY_H +#define DATASHARESERVICE_CONNECT_EXTENSION_STRAGETY_H + +#include "block_data.h" +#include "strategy.h" +namespace OHOS::DataShare { +class ConnectExtensionStrategy final : public Strategy { +public: + ConnectExtensionStrategy(); + bool operator()(std::shared_ptr context) override; + static bool Execute(std::shared_ptr context, std::function isFinished, int maxWaitTimeMs = 2000); +private: + inline bool Connect(std::shared_ptr context); + std::mutex mutex_; + BlockData data_; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..260e54423a4fbdef285fdfb16fc27b930a559942 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.cpp @@ -0,0 +1,24 @@ +/* + * 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 "EmptyStrategy" + +#include "empty_strategy.h" + +namespace OHOS::DataShare { +bool EmptyStrategy::operator()(std::shared_ptr context) +{ + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..a08e2bfc3eb15d754c76c67858bc661485740318 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/empty_strategy.h @@ -0,0 +1,26 @@ +/* + * 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 DATASHARESERVICE_EMPTY_STRAGETY_H +#define DATASHARESERVICE_EMPTY_STRAGETY_H + +#include "strategy.h" +namespace OHOS::DataShare { +class EmptyStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f9a931d4db75893c937f2614622a09398b80c02 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp @@ -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. + */ +#define LOG_TAG "LoadConfigCommonStrategy" +#include "load_config_common_strategy.h" + +#include "account/account_delegate.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "uri_utils.h" + +namespace OHOS::DataShare { +bool LoadConfigCommonStrategy::operator()(std::shared_ptr context) +{ + context->callerTokenId = IPCSkeleton::GetCallingTokenID(); + context->currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(context->callerTokenId); + // single app, userId is in uri + if (context->currentUserId == 0) { + URIUtils::GetUserIdFromProxyURI(context->uri, context->currentUserId); + } + FormatUri(context->uri); + return true; +} + +void LoadConfigCommonStrategy::FormatUri(std::string &uri) +{ + auto pos = uri.find('?'); + if (pos == std::string::npos) { + return; + } + + uri = uri.substr(0, pos); +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..9847158ae8a375ff28215fce65b25fcfed7bc1a3 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.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 DATASHARESERVICE_LOAD_CONFIG_COMMON_STRAGETY_H +#define DATASHARESERVICE_LOAD_CONFIG_COMMON_STRAGETY_H + +#include "strategy.h" +namespace OHOS::DataShare { +class LoadConfigCommonStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; + +private: + void FormatUri(std::string &uri); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..392856216c58df5107be48f511b210857605804f --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp @@ -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. + */ +#define LOG_TAG "LoadConfigDataInfoStrategy" +#include "load_config_data_info_strategy.h" + +#include "check_is_single_app_strategy.h" +#include "connect_extension_strategy.h" +#include "device_manager_adapter.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data.h" +#include "rdb_errno.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +LoadConfigDataInfoStrategy::LoadConfigDataInfoStrategy() + : DivStrategy(std::make_shared(), std::make_shared(), + std::make_shared()) +{ +} +static bool QueryMetaData(const std::string &bundleName, const std::string &storeName, + DistributedData::StoreMetaData &metaData, const int32_t userId) +{ + DistributedData::StoreMetaData meta; + meta.deviceId = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + meta.user = std::to_string(userId); + meta.bundleName = bundleName; + meta.storeId = storeName; + bool isCreated = DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), metaData); + if (!isCreated) { + ZLOGE("DB not exist"); + return false; + } + return true; +} + +bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr context) +{ + if (context->type != "rdb") { + return false; + } + DistributedData::StoreMetaData metaData; + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { + // connect extension and retry + if (!ConnectExtensionStrategy::Execute(context, [&context, &metaData]() { + return QueryMetaData( + context->calledBundleName, context->calledStoreName, metaData, context->currentUserId); + })) { + ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + context->errCode = NativeRdb::E_DB_NOT_EXIST; + return false; + } + } + context->calledSourceDir = metaData.dataDir; + context->version = metaData.version; + return true; +} + +bool LoadConfigSingleDataInfoStrategy::operator()(std::shared_ptr context) +{ + DistributedData::StoreMetaData metaData; + if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { + // connect extension and retry + if (!ConnectExtensionStrategy::Execute(context, [&context, &metaData]() { + return QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0); + })) { + ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + context->errCode = NativeRdb::E_DB_NOT_EXIST; + return false; + } + } + context->calledSourceDir = metaData.dataDir; + context->version = metaData.version; + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..54d0dad8637b2f909bc5f7ae75718db1c714a3da --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.h @@ -0,0 +1,34 @@ +/* + * 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 DATASHARESERVICE_LOAD_CONFIG_DATA_INFO_STRAGETY_H +#define DATASHARESERVICE_LOAD_CONFIG_DATA_INFO_STRAGETY_H + +#include "div_strategy.h" +namespace OHOS::DataShare { +class LoadConfigSingleDataInfoStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +class LoadConfigNormalDataInfoStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +class LoadConfigDataInfoStrategy final : public DivStrategy { +public: + LoadConfigDataInfoStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e70849ed12c6f6af7a63b7454bebdfc9e82292f2 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.cpp @@ -0,0 +1,27 @@ +/* + * 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 "load_config_from_bundle_info_strategy.h" + +#include "check_is_data_proxy_strategy.h" +#include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "data_share/load_config_from_data_share_bundle_info_strategy.h" + +namespace OHOS::DataShare { +LoadConfigFromBundleInfoStrategy::LoadConfigFromBundleInfoStrategy() + : DivStrategy(std::make_shared(), std::make_shared(), + std::make_shared()) +{ +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..d2801222cb4d55974648698ac979a3e24df40d43 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/load_config_from_bundle_info_strategy.h @@ -0,0 +1,26 @@ +/* + * 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 DATASHARESERVICE_LOAD_CONFIG_FROM_BUNDLE_INFO_STRAGETY_H +#define DATASHARESERVICE_LOAD_CONFIG_FROM_BUNDLE_INFO_STRAGETY_H + +#include "div_strategy.h" +namespace OHOS::DataShare { +class LoadConfigFromBundleInfoStrategy final: public DivStrategy { +public: + LoadConfigFromBundleInfoStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86a4ffbae233292e822d99e809fa31035bb1477b --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.cpp @@ -0,0 +1,39 @@ +/* + * 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 "PermissionStrategy" + +#include "permission_strategy.h" + +#include "accesstoken_kit.h" +#include "log_print.h" + +namespace OHOS::DataShare { +bool PermissionStrategy::operator()(std::shared_ptr context) +{ + if (context->permission == "reject") { + return false; + } + if (!context->permission.empty()) { + int status = + Security::AccessToken::AccessTokenKit::VerifyAccessToken(context->callerTokenId, context->permission); + if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + ZLOGE("Verify permission denied! callerTokenId:%{public}u permission:%{public}s", + context->callerTokenId, context->permission.c_str()); + return false; + } + } + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..467d868e6e96193ba20bd096404384299d039026 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/permission_strategy.h @@ -0,0 +1,27 @@ +/* + * 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 DATASHARESERVICE_PERMISSION_STRAGETY_H +#define DATASHARESERVICE_PERMISSION_STRAGETY_H + +#include "strategy.h" +namespace OHOS::DataShare { +class PermissionStrategy final : public Strategy { +public: + PermissionStrategy() = default; + bool operator()(std::shared_ptr context) override; +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3d19c332f5f3a63da479fa7275fa3498ae81141 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.cpp @@ -0,0 +1,43 @@ +/* + * 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 "ProcessUserCrossStrategy" +#include "process_single_app_user_cross_strategy.h" + +#include "bundlemgr/bundle_mgr_client.h" +#include "check_is_single_app_strategy.h" +#include "empty_strategy.h" +#include "log_print.h" + +namespace OHOS::DataShare { +ProcessSingleAppUserCrossStrategy::ProcessSingleAppUserCrossStrategy() + : DivStrategy(std::make_shared(), std::make_shared(), + std::make_shared()) +{ +} + +bool ProcessUserCrossStrategy::operator()(std::shared_ptr context) +{ + if (context->accessSystemMode == UNDEFINED) { + ZLOGE("single app must config user cross mode, please check it, bundleName: %{public}s", + context->calledBundleName.c_str()); + return false; + } + if (context->accessSystemMode == USER_SINGLE_MODE) { + context->calledTableName.append("_").append(std::to_string(context->currentUserId)); + return true; + } + return true; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.h b/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..1e2be33bccf52c0d17ba1a1ead6bd20b32b7cdb5 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/general/process_single_app_user_cross_strategy.h @@ -0,0 +1,30 @@ +/* + * 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 DATASHARESERVICE_PROCESS_SINGLE_APP_USER_CROSS_STRAGETY_H +#define DATASHARESERVICE_PROCESS_SINGLE_APP_USER_CROSS_STRAGETY_H + +#include "div_strategy.h" +namespace OHOS::DataShare { +class ProcessUserCrossStrategy final : public Strategy { +public: + bool operator()(std::shared_ptr context) override; +}; +class ProcessSingleAppUserCrossStrategy final : public DivStrategy { +public: + ProcessSingleAppUserCrossStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d5e432b139bfc7e5573679faf8c74e856b88e8e --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp @@ -0,0 +1,62 @@ +/* + * 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 "GetDataStrategy" + +#include "get_data_strategy.h" + +#include "general/load_config_common_strategy.h" +#include "general/permission_strategy.h" +#include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +Data GetDataStrategy::Execute(std::shared_ptr context) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return Data(); + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return Data(); + } + return Data(); +} + +Strategy *GetDataStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow) LoadConfigCommonStrategy(), + new (std::nothrow) LoadConfigFromDataProxyNodeStrategy(), + new (std::nothrow) PermissionStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..062f2a790e7b7253a3888a6e8ebeea52ef7e938a --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/get_data_strategy.h @@ -0,0 +1,33 @@ +/* + * 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 DATASHARESERVICE_GET_DATA_STRAGETY_H +#define DATASHARESERVICE_GET_DATA_STRAGETY_H + +#include + +#include "data_proxy_observer.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class GetDataStrategy final { +public: + static Data Execute(std::shared_ptr context); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/insert_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..792ead9cf5e8ce30298ac3ca9dd1579ba73f3272 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/insert_strategy.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. + */ +#define LOG_TAG "InsertStrategy" + +#include "insert_strategy.h" + +#include "db_delegate.h" +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/load_config_from_bundle_info_strategy.h" +#include "general/permission_strategy.h" +#include "general/process_single_app_user_cross_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +int64_t InsertStrategy::Execute(std::shared_ptr context, const DataShareValuesBucket &valuesBucket) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return -1; + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return -1; + } + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + if (delegate == nullptr) { + ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); + return -1; + } + return delegate->Insert(context->calledTableName, valuesBucket); +} + +Strategy *InsertStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromBundleInfoStrategy(), + new (std::nothrow)PermissionStrategy(), + new (std::nothrow)LoadConfigDataInfoStrategy(), + new (std::nothrow)ProcessSingleAppUserCrossStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/insert_strategy.h b/services/distributeddataservice/service/data_share/strategies/insert_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..c54720183ebe593660d6cacbba44a7776356d370 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/insert_strategy.h @@ -0,0 +1,32 @@ +/* + * 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 DATASHARESERVICE_INSERT_STRAGETY_H +#define DATASHARESERVICE_INSERT_STRAGETY_H + +#include + +#include "datashare_values_bucket.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class InsertStrategy final { +public: + static int64_t Execute(std::shared_ptr context, const DataShareValuesBucket &valuesBucket); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d658954cf5951ea758a578e90118b2875eb8921c --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp @@ -0,0 +1,62 @@ +/* + * 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 "PublishStrategy" + +#include "publish_strategy.h" + +#include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "general/load_config_common_strategy.h" +#include "general/permission_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +int32_t PublishStrategy::Execute(std::shared_ptr context, const PublishedDataItem &item) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return -1; + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return -1; + } + return 0; +} + +Strategy *PublishStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow) LoadConfigCommonStrategy(), + new (std::nothrow) LoadConfigFromDataProxyNodeStrategy(), + new (std::nothrow) PermissionStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/publish_strategy.h b/services/distributeddataservice/service/data_share/strategies/publish_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..70acdf7c51d123b5278e82b6b722412253da54eb --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/publish_strategy.h @@ -0,0 +1,33 @@ +/* + * 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 DATASHARESERVICE_PUBLISH_STRAGETY_H +#define DATASHARESERVICE_PUBLISH_STRAGETY_H + +#include + +#include "data_proxy_observer.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class PublishStrategy final { +public: + static int32_t Execute(std::shared_ptr context, const PublishedDataItem &item); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c2e2852a71f82df94e1ec6673a54933cd4bc3b16 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/query_strategy.cpp @@ -0,0 +1,74 @@ +/* + * 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 "QueryStrategy" + +#include "query_strategy.h" + +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/load_config_from_bundle_info_strategy.h" +#include "general/permission_strategy.h" +#include "general/process_single_app_user_cross_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +std::shared_ptr QueryStrategy::Execute( + std::shared_ptr context, const DataSharePredicates &predicates, + const std::vector &columns, int &errCode) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return nullptr; + } + if (!(*preProcess)(context)) { + errCode = context->errCode; + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return nullptr; + } + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + if (delegate == nullptr) { + ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); + return nullptr; + } + return delegate->Query(context->calledTableName, predicates, columns, errCode); +} + +Strategy *QueryStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromBundleInfoStrategy(), + new (std::nothrow)PermissionStrategy(), + new (std::nothrow)LoadConfigDataInfoStrategy(), + new (std::nothrow)ProcessSingleAppUserCrossStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/query_strategy.h b/services/distributeddataservice/service/data_share/strategies/query_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..13b0186f7dc9997aa43d3f61e2654c2c7e7dc7b2 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/query_strategy.h @@ -0,0 +1,34 @@ +/* + * 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 DATASHARESERVICE_QUERY_STRAGETY_H +#define DATASHARESERVICE_QUERY_STRAGETY_H + +#include + +#include "seq_strategy.h" +#include "rdb_delegate.h" + +namespace OHOS::DataShare { +class QueryStrategy final { +public: + static std::shared_ptr Execute(std::shared_ptr context, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3835435c8772ae161b77900e8b4c1d58d3f8ce34 --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.cpp @@ -0,0 +1,62 @@ +/* + * 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 "SubscribeStrategy" + +#include "subscribe_strategy.h" + +#include "data_proxy/load_config_from_data_proxy_node_strategy.h" +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/permission_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +int32_t SubscribeStrategy::Execute(std::shared_ptr context, std::function process) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return -1; + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri_: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return context->errCode; + } + return process(); +} +Strategy *SubscribeStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromDataProxyNodeStrategy(), + new (std::nothrow)PermissionStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..f11c4a6d9a7e746b17b8f5ed94533f77fd255a3a --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/subscribe_strategy.h @@ -0,0 +1,32 @@ +/* + * 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 DATASHARESERVICE_SUBSCRIBE_STRAGETY_H +#define DATASHARESERVICE_SUBSCRIBE_STRAGETY_H + +#include +#include "seq_strategy.h" +#include "data_proxy_observer.h" + +namespace OHOS::DataShare { +class SubscribeStrategy final { +public: + static int32_t Execute(std::shared_ptr context, std::function process); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp b/services/distributeddataservice/service/data_share/strategies/update_strategy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..800832ac0925e7f3eec8c47002253afa2c4c971b --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/update_strategy.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. + */ +#define LOG_TAG "UpdateStrategy" + +#include "update_strategy.h" + +#include "general/load_config_common_strategy.h" +#include "general/load_config_data_info_strategy.h" +#include "general/load_config_from_bundle_info_strategy.h" +#include "general/permission_strategy.h" +#include "general/process_single_app_user_cross_strategy.h" +#include "log_print.h" +#include "utils/anonymous.h" + +namespace OHOS::DataShare { +int64_t UpdateStrategy::Execute( + std::shared_ptr context, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) +{ + auto preProcess = GetStrategy(); + if (preProcess == nullptr) { + ZLOGE("get strategy fail, maybe memory not enough"); + return -1; + } + if (!(*preProcess)(context)) { + ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); + return -1; + } + auto delegate = DBDelegate::Create(context->calledSourceDir, context->version); + if (delegate == nullptr) { + ZLOGE("malloc fail %{public}s %{public}s", context->calledBundleName.c_str(), context->calledTableName.c_str()); + return -1; + } + return delegate->Update(context->calledTableName, predicate, valuesBucket); +} + +Strategy *UpdateStrategy::GetStrategy() +{ + static std::mutex mutex; + static SeqStrategy strategies; + std::lock_guard lock(mutex); + if (!strategies.IsEmpty()) { + return &strategies; + } + std::initializer_list list = { + new (std::nothrow)LoadConfigCommonStrategy(), + new (std::nothrow)LoadConfigFromBundleInfoStrategy(), + new (std::nothrow)PermissionStrategy(), + new (std::nothrow)LoadConfigDataInfoStrategy(), + new (std::nothrow)ProcessSingleAppUserCrossStrategy() + }; + auto ret = strategies.Init(list); + if (!ret) { + std::for_each(list.begin(), list.end(), [](Strategy *item) { + delete item; + }); + return nullptr; + } + return &strategies; +} +} // namespace OHOS::DataShare \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/strategies/update_strategy.h b/services/distributeddataservice/service/data_share/strategies/update_strategy.h new file mode 100644 index 0000000000000000000000000000000000000000..4ee54764f2ddf4dc18cc57ac4f2edd302cb74b8b --- /dev/null +++ b/services/distributeddataservice/service/data_share/strategies/update_strategy.h @@ -0,0 +1,35 @@ +/* + * 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 DATASHARESERVICE_UPDATE_STRAGETY_H +#define DATASHARESERVICE_UPDATE_STRAGETY_H + +#include + +#include "context.h" +#include "rdb_delegate.h" +#include "seq_strategy.h" + +namespace OHOS::DataShare { +class UpdateStrategy final { +public: + static int64_t Execute(std::shared_ptr context, const DataSharePredicates &predicate, + const DataShareValuesBucket &valuesBucket); + +private: + static Strategy *GetStrategy(); +}; +} // namespace OHOS::DataShare +#endif diff --git a/services/distributeddataservice/service/directory/src/directory_manager.cpp b/services/distributeddataservice/service/directory/src/directory_manager.cpp index eba3ef8959f5e574a921e40b9eb9395a716ef18b..bba79049e25fd98a4fab5c5f06464d95d9d9433f 100644 --- a/services/distributeddataservice/service/directory/src/directory_manager.cpp +++ b/services/distributeddataservice/service/directory/src/directory_manager.cpp @@ -208,7 +208,7 @@ std::vector DirectoryManager::GetVersions() { std::vector versions; for (size_t i = 0; i < strategies_.size(); ++i) { - versions[i] = strategies_[i].version; + versions.push_back(strategies_[i].version); } return versions; } diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 6e19c96a6d5fea542814a9f10e500afaedeaa2b0..8428cb58d63598b95eb56cdf3913afef3ee6dd46 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -39,7 +39,6 @@ #include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" -#include "utils/crypto.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; using namespace OHOS::AppDistributedKv; @@ -166,7 +165,7 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const S MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); auto delay = GetSyncDelayTime(syncInfo.delay, storeId); if (metaData.isAutoSync && syncInfo.seqId == std::numeric_limits::max()) { - DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::GetInstance().GetCode(metaData)); + DeviceMatrix::GetInstance().OnChanged(metaData); StoreMetaDataLocal localMeta; MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyLocal(), localMeta, true); if (!localMeta.HasPolicy(IMMEDIATE_SYNC_ON_CHANGE)) { @@ -351,36 +350,6 @@ Status KVDBServiceImpl::GetBackupPassword(const AppId &appId, const StoreId &sto return (BackupManager::GetInstance().GetPassWord(metaData, password)) ? SUCCESS : ERROR; } -KVDBService::DevBrief KVDBServiceImpl::GetLocalDevice() -{ - DevBrief brief; - CheckerManager::StoreInfo storeInfo; - storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); - storeInfo.uid = IPCSkeleton::GetCallingPid(); - auto appId = CheckerManager::GetInstance().GetAppId(storeInfo); - auto device = DMAdapter::GetInstance().GetLocalDevice(); - brief.networkId = std::move(device.networkId); - brief.uuid = Crypto::Sha256(appId + "_" + device.uuid); - return brief; -} - -std::vector KVDBServiceImpl::GetRemoteDevices() -{ - std::vector briefs; - CheckerManager::StoreInfo storeInfo; - storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); - storeInfo.uid = IPCSkeleton::GetCallingPid(); - auto appId = CheckerManager::GetInstance().GetAppId(storeInfo); - auto devices = DMAdapter::GetInstance().GetRemoteDevices(); - for (const auto &device : devices) { - DevBrief brief; - brief.networkId = std::move(device.networkId); - brief.uuid = Crypto::Sha256(appId + "_" + device.uuid); - briefs.push_back(std::move(brief)); - } - return briefs; -} - Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) { ZLOGD("appId:%{public}s storeId:%{public}s to export data", appId.appId.c_str(), storeId.storeId.c_str()); @@ -523,17 +492,19 @@ int32_t KVDBServiceImpl::OnReady(const std::string &device) if (!data.isAutoSync) { continue; } + ZLOGI("[onReady] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), data.storeId.c_str()); StoreMetaDataLocal localMetaData; MetaDataManager::GetInstance().LoadMeta(data.GetKeyLocal(), localMetaData, true); - if (!localMetaData.HasPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY)) { + if (!localMetaData.HasPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY) && + (!localMetaData.HasPolicy(PolicyType::TERM_OF_SYNC_VALIDITY) || + !DeviceMatrix::GetInstance().IsChangedInTerm(data, + localMetaData.GetPolicy(PolicyType::TERM_OF_SYNC_VALIDITY).valueUint))) { continue; } - auto policy = localMetaData.GetPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY); SyncInfo syncInfo; - syncInfo.mode = PUSH_PULL; - syncInfo.delay = policy.IsValueEffect() ? policy.valueUint : 0; + syncInfo.delay = localMetaData.HasPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY) ? + localMetaData.GetPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY).valueUint : 0; syncInfo.devices = { device }; - ZLOGI("[onReady] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), data.storeId.c_str()); auto delay = GetSyncDelayTime(syncInfo.delay, { data.storeId }); KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(data.tokenId), delay, std::bind(&KVDBServiceImpl::DoSync, this, data, syncInfo, std::placeholders::_1, ACTION_SYNC), @@ -819,4 +790,12 @@ size_t KVDBServiceImpl::GetSyncDataSize(const std::string &deviceId) return totalSize; } +int32_t KVDBServiceImpl::OnExecutor(std::shared_ptr executors) +{ + executors_ = executors; + storeCache_.SetThreadPool(executors); + KvStoreSyncManager::GetInstance()->SetThreadPool(executors); + ZLOGE("onexecutor:%{public}p", executors.get()); + return 0; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index 72dddfc472b4dbe3ee883f840d90ae1ad62fbeeb..b1c3e5fd07d5bc8a27e90b74533842cd1d0a64b6 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -53,9 +53,7 @@ public: Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; - DevBrief GetLocalDevice() override; - std::vector GetRemoteDevices() override; - + int32_t OnExecutor(std::shared_ptr executors) 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; @@ -107,6 +105,7 @@ private: static Factory factory_; ConcurrentMap syncAgents_; StoreCache storeCache_; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_IMPL_H diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 95e333dc2fd5dae97b6e19c61d104d7b6e689624..61fdde59d2b3d0c3df0b738173138307d6a6a7ec 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -40,8 +40,6 @@ const KVDBServiceStub::Handler KVDBServiceStub::HANDLERS[TRANS_BUTT] = { &KVDBServiceStub::OnSubscribe, &KVDBServiceStub::OnUnsubscribe, &KVDBServiceStub::OnGetBackupPassword, - &KVDBServiceStub::OnGetLocalDevice, - &KVDBServiceStub::OnGetRemoteDevices, }; int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) @@ -61,9 +59,6 @@ int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message AppId appId; StoreId storeId; - if (TRANS_NO_APPID_BEGIN <= code && code <= TRANS_NO_APPID_END) { - return (this->*HANDLERS[code])(appId, storeId, data, reply); - } if (!ITypesUtil::Unmarshal(data, appId, storeId)) { ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); return IPC_STUB_INVALID_DATA_ERR; @@ -225,34 +220,6 @@ int32_t KVDBServiceStub::OnGetSyncParam( return ERR_NONE; } -int32_t KVDBServiceStub::OnGetLocalDevice( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) -{ - (void)appId; - (void)storeId; - int32_t status = SUCCESS; - auto brief = GetLocalDevice(); - if (!ITypesUtil::Marshal(reply, status, brief)) { - ZLOGE("Marshal device brief:{%{public}u, %{public}u}", brief.networkId.empty(), brief.uuid.empty()); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return ERR_NONE; -} - -int32_t KVDBServiceStub::OnGetRemoteDevices( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) -{ - (void)appId; - (void)storeId; - int32_t status = SUCCESS; - auto briefs = GetRemoteDevices(); - if (!ITypesUtil::Marshal(reply, status, briefs)) { - ZLOGE("Marshal device brief:%{public}zu", briefs.size()); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return ERR_NONE; -} - int32_t KVDBServiceStub::OnEnableCap( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index 8b5f8b9003c52b4b4aaa896e5b32d57808e1ef0c..ab0bacc494d2e6df8019b6a077d2e563102f7c99 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -43,8 +43,6 @@ private: int32_t OnSubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnUnsubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetBackupPassword(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnGetLocalDevice(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnGetRemoteDevices(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); static const Handler HANDLERS[TRANS_BUTT]; }; } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.cpp b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.cpp index d2610983872942b2ae54b9e092e96748c8bc7a08..ac011bcf4613f1fe6636f2f6f5069cf0541dc744 100644 --- a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.cpp +++ b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.cpp @@ -18,9 +18,7 @@ namespace OHOS { namespace DistributedKv { -KvStoreSyncManager::KvStoreSyncManager() : syncScheduler_("SyncMgr") -{} - +KvStoreSyncManager::KvStoreSyncManager() {} KvStoreSyncManager::~KvStoreSyncManager() {} Status KvStoreSyncManager::AddSyncOperation(uintptr_t syncId, uint32_t delayMs, const SyncFunc &syncFunc, @@ -112,7 +110,11 @@ void KvStoreSyncManager::AddTimer(const TimePoint &expireTime) { ZLOGD("time %lld", expireTime.time_since_epoch().count()); nextScheduleTime_ = expireTime; - syncScheduler_.At(expireTime, [time = expireTime, this]() { Schedule(time); }); + executors_->Schedule( + expireTime - std::chrono::steady_clock::now(), + [time = expireTime, this]() { + Schedule(time); + }); } bool KvStoreSyncManager::GetTimeoutSyncOps(const TimePoint ¤tTime, std::list &syncOps) @@ -175,5 +177,9 @@ void KvStoreSyncManager::Schedule(const TimePoint &time) AddTimer(nextTime); } } -} // namespace DistributedKv -} // namespace OHOS +void KvStoreSyncManager::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} +} // namespace DistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h index 1376358c67f82124a533d7545088d6f086103835..bad171c5225e9d53b30e808a38fa3afd9e4a3ee9 100644 --- a/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h +++ b/services/distributeddataservice/service/kvdb/kvstore_sync_manager.h @@ -20,7 +20,7 @@ #include #include -#include "task_scheduler.h" +#include "executor_pool.h" #include "kv_store_nb_delegate.h" #include "types.h" @@ -50,6 +50,7 @@ public: TimePoint beginTime; }; using OpPred = std::function; + void SetThreadPool(std::shared_ptr executors); Status AddSyncOperation(uintptr_t syncId, uint32_t delayMs, const SyncFunc &syncFunc, const SyncEnd &syncEnd); Status RemoveSyncOperation(uintptr_t syncId); @@ -73,8 +74,8 @@ private: std::list realtimeSyncingOps_; std::list delaySyncingOps_; std::multimap scheduleSyncOps_; + std::shared_ptr executors_; - TaskScheduler syncScheduler_ { "sync_mgr" }; TimePoint nextScheduleTime_; std::atomic_uint32_t syncOpSeq_ = 0; }; diff --git a/services/distributeddataservice/service/kvdb/store_cache.cpp b/services/distributeddataservice/service/kvdb/store_cache.cpp index 80574e51c91a93b9c916ecfd8a1173ec4ef9e37e..093e8e5a9fc95f3868e8045149114ef34123ae01 100644 --- a/services/distributeddataservice/service/kvdb/store_cache.cpp +++ b/services/distributeddataservice/service/kvdb/store_cache.cpp @@ -25,7 +25,6 @@ namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; constexpr int64_t StoreCache::INTERVAL; -constexpr size_t StoreCache::TIME_TASK_NUM; StoreCache::Store StoreCache::GetStore(const StoreMetaData &data, std::shared_ptr observers, DBStatus &status) { @@ -65,9 +64,7 @@ StoreCache::Store StoreCache::GetStore(const StoreMetaData &data, std::shared_pt return !stores.empty(); }); - scheduler_.At(std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL), - std::bind(&StoreCache::GarbageCollect, this)); - + executors_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); return store; } @@ -134,7 +131,7 @@ void StoreCache::GarbageCollect() }); if (!stores_.Empty()) { ZLOGD("stores size:%{public}zu", stores_.Size()); - scheduler_.At(current + std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); + executors_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); } } @@ -194,6 +191,11 @@ StoreCache::DBPassword StoreCache::GetDBPassword(const StoreMetaData &data) return dbPassword; } +void StoreCache::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} + StoreCache::DBStoreDelegate::DBStoreDelegate(DBStore *delegate, std::shared_ptr observers) : delegate_(delegate) { diff --git a/services/distributeddataservice/service/kvdb/store_cache.h b/services/distributeddataservice/service/kvdb/store_cache.h index 10a4c8722f92f77c54b8fe505eff152d988c6692..2e4d726c32ef6bfeec899e8192ccf5e1573a8674 100644 --- a/services/distributeddataservice/service/kvdb/store_cache.h +++ b/services/distributeddataservice/service/kvdb/store_cache.h @@ -15,16 +15,17 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_STORE_CACHE_H #define OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_STORE_CACHE_H -#include #include +#include #include #include + #include "concurrent_map.h" -#include "task_scheduler.h" +#include "executor_pool.h" +#include "ikvstore_observer.h" #include "kv_store_nb_delegate.h" #include "metadata/store_meta_data.h" #include "refbase.h" -#include "ikvstore_observer.h" namespace OHOS::DistributedKv { class StoreCache { @@ -75,12 +76,12 @@ public: static DBOption GetDBOption(const StoreMetaData &data, const DBPassword &password); static DBSecurity GetDBSecurity(int32_t secLevel); static DBPassword GetDBPassword(const StoreMetaData &data); + void SetThreadPool(std::shared_ptr executors); private: void GarbageCollect(); static constexpr int64_t INTERVAL = 1; - static constexpr size_t TIME_TASK_NUM = 1; ConcurrentMap> stores_; - TaskScheduler scheduler_{ TIME_TASK_NUM, "store_cache" }; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_STORE_CACHE_H diff --git a/services/distributeddataservice/service/kvdb/upgrade.cpp b/services/distributeddataservice/service/kvdb/upgrade.cpp index 8220ef8392ddaf2539a68fadb704301786e3024b..ea40a6bd1de21eb555e09ba4afd6e0cc2c881c91 100644 --- a/services/distributeddataservice/service/kvdb/upgrade.cpp +++ b/services/distributeddataservice/service/kvdb/upgrade.cpp @@ -20,12 +20,18 @@ #include "crypto_manager.h" #include "metadata/secret_key_meta_data.h" +#include "device_manager_adapter.h" +#include "log_print.h" #include "metadata/meta_data_manager.h" #include "store_cache.h" +#include "accesstoken_kit.h" #include "directory_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; using system_clock = std::chrono::system_clock; +using DMAdapter = DistributedData::DeviceManagerAdapter; +using DBKey = DistributedDB::Key; + Upgrade &Upgrade::GetInstance() { static Upgrade upgrade; @@ -34,6 +40,13 @@ Upgrade &Upgrade::GetInstance() Upgrade::DBStatus Upgrade::UpdateStore(const StoreMeta &old, const StoreMeta &meta, const std::vector &pwd) { + if (old.version < StoreMeta::UUID_CHANGED_TAG && old.storeType == DEVICE_COLLABORATION) { + auto upStatus = Upgrade::GetInstance().UpdateUuid(old, meta, pwd); + if (upStatus != DBStatus::OK) { + return DBStatus::DB_ERROR; + } + } + if (old.dataDir == meta.dataDir) { return DBStatus::OK; } @@ -89,6 +102,28 @@ void Upgrade::UpdatePassword(const StoreMeta &meta, const std::vector & MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), secretKey, true); } +Upgrade::DBStatus Upgrade::UpdateUuid(const StoreMeta &old, const StoreMeta &meta, const std::vector &pwd) +{ + auto kvStore = GetDBStore(meta, pwd); + if (kvStore == nullptr) { + return DBStatus::DB_ERROR; + } + kvStore->RemoveDeviceData(); + auto uuid = GetEncryptedUuidByMeta(meta); + auto dbStatus = kvStore->UpdateKey([uuid](const DBKey &originKey, DBKey &newKey) { + newKey = originKey; + errno_t err = EOK; + err = memcpy_s(newKey.data(), newKey.size(), uuid.data(), uuid.size()); + if (err != EOK) { + ZLOGE("memcpy_s failed, err:%{public}d", err); + } + }); + if (dbStatus != DBStatus::OK) { + ZLOGE("fail to update Uuid, status:%{public}d", dbStatus); + } + return dbStatus; +} + bool Upgrade::RegisterExporter(uint32_t version, Exporter exporter) { (void)version; @@ -117,4 +152,23 @@ Upgrade::AutoStore Upgrade::GetDBStore(const StoreMeta &meta, const std::vector< }); return dbStore; } + +std::string Upgrade::GetEncryptedUuidByMeta(const StoreMeta &meta) +{ + std::string keyUuid = meta.appId + meta.deviceId; + auto pair = calcUuid_.Find(keyUuid); + if (pair.first) { + return pair.second; + } + std::string uuid; + if (OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(meta.tokenId) == + OHOS::Security::AccessToken::TOKEN_HAP) { + uuid = DMAdapter::GetInstance().CalcClientUuid(meta.appId, meta.deviceId); + calcUuid_.Insert(keyUuid, uuid); + return uuid; + } + uuid = DMAdapter::GetInstance().CalcClientUuid(" ", meta.deviceId); + calcUuid_.Insert(keyUuid, uuid); + return uuid; +} } \ No newline at end of file diff --git a/services/distributeddataservice/service/kvdb/upgrade.h b/services/distributeddataservice/service/kvdb/upgrade.h index 62644591a6610542ed11e731202490339e9e8d20..b6d83b02d7fcc8b1b20e66c31d15f559f8cd24c0 100644 --- a/services/distributeddataservice/service/kvdb/upgrade.h +++ b/services/distributeddataservice/service/kvdb/upgrade.h @@ -17,10 +17,13 @@ #define OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_UPGRADE_H #include #include + #include "kv_store_delegate_manager.h" #include "kv_store_nb_delegate.h" #include "metadata/store_meta_data.h" #include "types.h" +#include "concurrent_map.h" + namespace OHOS::DistributedKv { class Upgrade { public: @@ -31,6 +34,7 @@ public: using DBManager = DistributedDB::KvStoreDelegateManager; using Exporter = std::function; using Cleaner = std::function; + API_EXPORT static Upgrade &GetInstance(); API_EXPORT bool RegisterExporter(uint32_t version, Exporter exporter); API_EXPORT bool RegisterCleaner(uint32_t version, Cleaner cleaner); @@ -38,10 +42,14 @@ public: DBStatus UpdateStore(const StoreMeta &old, const StoreMeta &metaData, const std::vector &pwd); DBStatus ExportStore(const StoreMeta &old, const StoreMeta &meta); void UpdatePassword(const StoreMeta &meta, const std::vector &password); + DBStatus UpdateUuid(const StoreMeta &old, const StoreMeta &meta, const std::vector &pwd); + API_EXPORT std::string GetEncryptedUuidByMeta(const StoreMeta &meta); private: using AutoStore = std::unique_ptr>; AutoStore GetDBStore(const StoreMeta &meta, const std::vector &pwd); + ConcurrentMap calcUuid_; + Exporter exporter_; Cleaner cleaner_; }; diff --git a/services/distributeddataservice/service/kvdb/user_delegate.cpp b/services/distributeddataservice/service/kvdb/user_delegate.cpp index 5fbd181433602db4a06f619b54ae46b2abe5151b..2cd03d0fdfccc7d58c1ceb176695b4d2b7bd6b19 100644 --- a/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -18,7 +18,6 @@ #include #include "communicator/device_manager_adapter.h" -#include "executor_factory.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" @@ -53,12 +52,16 @@ std::set UserDelegate::GetLocalUsers() ZLOGE("failed to get local device id"); return {}; } - if (!deviceUserMap_.Contains(deviceId)) { - LoadFromMeta(deviceId); - } std::set users; - deviceUserMap_.ComputeIfPresent(deviceId, [&users](auto&, std::map &value) { - for (auto [user, active] : value) { + deviceUser_.Compute(deviceId, [&users](const auto &key, auto &value) { + if (value.empty()) { + UserMetaData userMetaData; + MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); + for (const auto &user : userMetaData.users) { + value[user.id] = user.isActive; + } + } + for (const auto [user, active] : value) { users.emplace(std::to_string(user)); } return !value.empty(); @@ -78,12 +81,19 @@ std::vector UserDelegate::GetRemoteUserStatus(const std::vector UserDelegate::GetUsers(const std::string &deviceId) { std::vector userStatus; - if (!deviceUserMap_.Contains(deviceId)) { - LoadFromMeta(deviceId); - } - for (const auto &entry : deviceUserMap_[deviceId]) { - userStatus.emplace_back(entry.first, entry.second); - } + deviceUser_.Compute(deviceId, [&userStatus](const auto &key, auto &users) { + if (users.empty()) { + UserMetaData userMetaData; + MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); + for (const auto &user : userMetaData.users) { + users[user.id] = user.isActive; + } + } + for (const auto [key, value] : users) { + userStatus.emplace_back(key, value); + } + return !users.empty(); + }); ZLOGI("device:%{public}s, users:%{public}s", Anonymous::Change(deviceId).c_str(), Serializable::Marshall(userStatus).c_str()); return userStatus; @@ -91,22 +101,20 @@ std::vector UserDelegate::GetUsers(const std::string &deviceId) void UserDelegate::DeleteUsers(const std::string &deviceId) { - deviceUserMap_.Erase(deviceId); + deviceUser_.Erase(deviceId); } void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector &userStatus) { - ZLOGI("begin, device:%{public}.10s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size()); - deviceUserMap_.Compute(deviceId, [&userStatus](const auto &key, std::map &userMap) { - userMap = {}; - for (auto &user : userStatus) { - userMap[user.id] = user.isActive; + ZLOGI("begin, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size()); + deviceUser_.Compute(deviceId, [&userStatus](const auto &key, std::map &users) { + users = {}; + for (const auto &user : userStatus) { + users[user.id] = user.isActive; } + ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(key).c_str(), users.size()); return true; }); - - ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), - deviceUserMap_[deviceId].size()); } bool UserDelegate::InitLocalUserMeta() @@ -124,45 +132,24 @@ bool UserDelegate::InitLocalUserMeta() UserMetaData userMetaData; userMetaData.deviceId = GetLocalDeviceId(); UpdateUsers(userMetaData.deviceId, userStatus); - for (auto &pair : deviceUserMap_[userMetaData.deviceId]) { - userMetaData.users.emplace_back(pair.first, pair.second); - } - + deviceUser_.ComputeIfPresent(userMetaData.deviceId, [&userMetaData](const auto &, std::map &users) { + for (const auto &[key, value] : users) { + userMetaData.users.emplace_back(key, value); + } + return true; + }); ZLOGI("put user meta data save meta data"); return MetaDataManager::GetInstance().SaveMeta(UserMetaRow::GetKeyFor(userMetaData.deviceId), userMetaData); } -void UserDelegate::LoadFromMeta(const std::string &deviceId) -{ - UserMetaData userMetaData; - MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(deviceId), userMetaData); - std::map userMap; - for (const auto &user : userMetaData.users) { - userMap[user.id] = user.isActive; - } - deviceUserMap_[deviceId] = userMap; -} - UserDelegate &UserDelegate::GetInstance() { static UserDelegate instance; return instance; } -void UserDelegate::Init() +void UserDelegate::Init(const std::shared_ptr& executors) { - KvStoreTask retryTask([this]() { - do { - static constexpr int RETRY_INTERVAL = 500; // millisecond - std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL)); - if (!InitLocalUserMeta()) { - continue; - } - break; - } while (true); - ZLOGI("update user meta ok"); - }); - auto ret = AccountDelegate::GetInstance()->Subscribe(std::make_shared(*this)); MetaDataManager::GetInstance().Subscribe( UserMetaRow::KEY_PREFIX, [this](const std::string &key, const std::string &value, int32_t flag) -> auto { @@ -182,12 +169,24 @@ void UserDelegate::Init() } return true; }); - if (!InitLocalUserMeta()) { - ExecutorFactory::GetInstance().Execute(std::move(retryTask)); + if (!executors_) { + executors_ = executors; } + executors_->Execute(GeTask()); ZLOGD("subscribe os account ret:%{public}d", ret); } +ExecutorPool::Task UserDelegate::GeTask() +{ + return [this] { + auto ret = InitLocalUserMeta(); + if (ret) { + return; + } + executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GeTask()); + }; +} + bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) { // update all local user status diff --git a/services/distributeddataservice/service/kvdb/user_delegate.h b/services/distributeddataservice/service/kvdb/user_delegate.h index fb3797d63837635d51dff7132e45e5672d0130c9..67009804580c361d442bccc6dd5cc2f7e272b877 100644 --- a/services/distributeddataservice/service/kvdb/user_delegate.h +++ b/services/distributeddataservice/service/kvdb/user_delegate.h @@ -20,6 +20,7 @@ #include #include "account/account_delegate.h" #include "concurrent_map.h" +#include "executor_pool.h" #include "metadata/user_meta_data.h" #include "visibility.h" @@ -34,7 +35,7 @@ public: }; API_EXPORT static UserDelegate &GetInstance(); - API_EXPORT void Init(); + API_EXPORT void Init(const std::shared_ptr& executors); API_EXPORT std::vector GetLocalUserStatus(); API_EXPORT std::set GetLocalUsers(); API_EXPORT std::vector GetRemoteUserStatus(const std::string &deviceId); @@ -56,13 +57,15 @@ private: UserDelegate &userDelegate_; }; std::vector GetUsers(const std::string &deviceId); - void LoadFromMeta(const std::string &deviceId); void UpdateUsers(const std::string &deviceId, const std::vector &userStatus); void DeleteUsers(const std::string &deviceId); bool NotifyUserEvent(const UserEvent &userEvent); + ExecutorPool::Task GeTask(); + static constexpr int RETRY_INTERVAL = 500; // millisecond + std::shared_ptr executors_; // device : { user : isActive } - ConcurrentMap> deviceUserMap_; + ConcurrentMap> deviceUser_; }; } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/service/matrix/include/device_matrix.h b/services/distributeddataservice/service/matrix/include/device_matrix.h index e660bc93b47146ce98adcf88fb0ddc2142881240..c04223aa48429ebb33f23d63c88b4be049c671b3 100644 --- a/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -24,6 +24,7 @@ namespace OHOS::DistributedData { class API_EXPORT DeviceMatrix { public: + using TimePoint = std::chrono::steady_clock::time_point; static constexpr uint16_t META_STORE_MASK = 0x0001; enum : int32_t { MATRIX_ONLINE = Event::EVT_CUSTOM, @@ -37,7 +38,9 @@ public: void Offline(const std::string &device); uint16_t OnBroadcast(const std::string &device, uint16_t code); void OnChanged(uint16_t code); + void OnChanged(const StoreMetaData &metaData); void OnExchanged(const std::string &device, uint16_t code, bool isRemote = false); + bool IsChangedInTerm(const StoreMetaData &metaData, uint64_t term); uint16_t GetCode(const StoreMetaData &metaData); void Clear(); @@ -72,6 +75,7 @@ private: std::map remotes_; std::vector maskApps_ = { "distributed_device_profile_service" }; LRUBucket versions_{ MAX_DEVICES }; + LRUBucket changeTime_ { 64 }; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H diff --git a/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/services/distributeddataservice/service/matrix/src/device_matrix.cpp index ab034dea0693153164651ae19a7e6d6ce2616dc1..2217be08db9564cf094f1f2a0997a6ce0b009401 100644 --- a/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -131,6 +131,24 @@ void DeviceMatrix::OnChanged(uint16_t code) } } +void DeviceMatrix::OnChanged(const StoreMetaData &metaData) +{ + auto code = GetCode(metaData); + if (code != 0) { + OnChanged(code); + } + changeTime_.Set(metaData.tokenId, std::chrono::steady_clock::now()); +} + +bool DeviceMatrix::IsChangedInTerm(const StoreMetaData &metaData, uint64_t term) +{ + TimePoint changeTime; + if (!changeTime_.Get(metaData.tokenId, changeTime, false)) { + return false; + } + return std::chrono::steady_clock::now() < (changeTime + std::chrono::seconds(term)); +} + void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, bool isRemote) { std::lock_guard lockGuard(mutex_); diff --git a/services/distributeddataservice/service/object/object_manager.cpp b/services/distributeddataservice/service/object/object_manager.cpp index f80a9290e9fa61a8015d5e00f23a2041926c163f..a911a5f8d3bd7362782a421c331c4a17d7fca20b 100644 --- a/services/distributeddataservice/service/object/object_manager.cpp +++ b/services/distributeddataservice/service/object/object_manager.cpp @@ -27,10 +27,7 @@ namespace OHOS { namespace DistributedObject { using namespace OHOS::DistributedKv; -ObjectStoreManager::ObjectStoreManager() : timer_("CloseRetryTimer") -{ - timer_.Setup(); -} +ObjectStoreManager::ObjectStoreManager() {} DistributedDB::KvStoreNbDelegate *ObjectStoreManager::OpenObjectKvStore() { @@ -353,7 +350,10 @@ void ObjectStoreManager::FlushClosedStore() ZLOGD("close store"); auto status = kvStoreDelegateManager_->CloseKvStore(delegate_); if (status != DistributedDB::DBStatus::OK) { - timer_.Register([this]() { FlushClosedStore(); }, 1000, true); // retry after 1000ms + int timeOut = 1000; + executors_->Schedule(std::chrono::milliseconds(timeOut), [this]() { + FlushClosedStore(); + }); ZLOGE("GetEntries fail %{public}d", status); return; } @@ -567,8 +567,7 @@ int64_t ObjectStoreManager::GetTime(const std::string &key) void ObjectStoreManager::CloseAfterMinute() { - scheduler_.At(std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL), - std::bind(&ObjectStoreManager::Close, this)); + executors_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&ObjectStoreManager::Close, this)); } std::string ObjectStoreManager::GetBundleName(const std::string &key) @@ -582,6 +581,11 @@ std::string ObjectStoreManager::GetBundleName(const std::string &key) return result; } +void ObjectStoreManager::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} + uint64_t SequenceSyncManager::AddNotifier(const std::string &userId, SyncCallBack &callback) { std::lock_guard lock(notifierLock_); diff --git a/services/distributeddataservice/service/object/object_manager.h b/services/distributeddataservice/service/object/object_manager.h index da5117b7f27f52b1fc362dfe71a3e11d1334d25e..d3d924def8660977b38927d9256b76913ba4fc46 100644 --- a/services/distributeddataservice/service/object/object_manager.h +++ b/services/distributeddataservice/service/object/object_manager.h @@ -22,12 +22,10 @@ #include "device_manager_adapter.h" #include "object_callback.h" #include "object_callback_proxy.h" -#include "task_scheduler.h" #include "kv_store_delegate_manager.h" #include "kvstore_sync_callback.h" #include "object_common.h" #include "object_data_listener.h" -#include "timer.h" #include "types.h" namespace OHOS { @@ -93,6 +91,7 @@ public: void NotifyChange(std::map> &changedData); void CloseAfterMinute(); int32_t Open(); + void SetThreadPool(std::shared_ptr executors); private: constexpr static const char *SEPERATOR = "_"; constexpr static const char *LOCAL_DEVICE = "local"; @@ -150,11 +149,10 @@ private: uint32_t syncCount_ = 0; std::string userId_; std::atomic isSyncing_ = false; - Utils::Timer timer_; ConcurrentMap callbacks_; static constexpr size_t TIME_TASK_NUM = 1; static constexpr int64_t INTERVAL = 1; - TaskScheduler scheduler_ { TIME_TASK_NUM, "object_mgr" }; + std::shared_ptr executors_; }; } // namespace DistributedObject } // namespace OHOS diff --git a/services/distributeddataservice/service/object/object_service_impl.cpp b/services/distributeddataservice/service/object/object_service_impl.cpp index 8b65f0ed8e49c45b62f0e0b3119506cd4c5f3efe..7ae417c363f1e5259c4a22870fec4317cb12e00c 100644 --- a/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/services/distributeddataservice/service/object/object_service_impl.cpp @@ -38,7 +38,12 @@ using FeatureSystem = OHOS::DistributedData::FeatureSystem; __attribute__((used)) ObjectServiceImpl::Factory ObjectServiceImpl::factory_; ObjectServiceImpl::Factory::Factory() { - FeatureSystem::GetInstance().RegisterCreator("data_object", []() { return std::make_shared(); }); + FeatureSystem::GetInstance().RegisterCreator( + "data_object", + []() { + return std::make_shared(); + }, + FeatureSystem::BIND_NOW); } ObjectServiceImpl::Factory::~Factory() @@ -272,4 +277,9 @@ int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, con ObjectServiceImpl::ObjectServiceImpl() { } +int32_t ObjectServiceImpl::OnExecutor(std::shared_ptr executors) +{ + executors_ = executors; + return 0; +} } // namespace OHOS::DistributedObject diff --git a/services/distributeddataservice/service/object/object_service_impl.h b/services/distributeddataservice/service/object/object_service_impl.h index a7f40e51c95912bec4e4e57c8d16c3d02a3329a8..932ea29afd3d15abfd8ca6e4cbb55789858c9589 100644 --- a/services/distributeddataservice/service/object/object_service_impl.h +++ b/services/distributeddataservice/service/object/object_service_impl.h @@ -42,6 +42,7 @@ public: 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 &appId) override; int32_t OnInitialize() override; + int32_t OnExecutor(std::shared_ptr executors) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; @@ -52,6 +53,7 @@ private: ~Factory(); }; static Factory factory_; + std::shared_ptr executors_; }; } // namespace OHOS::DistributedObject #endif diff --git a/services/distributeddataservice/service/object/object_service_stub.cpp b/services/distributeddataservice/service/object/object_service_stub.cpp index cf142a29218a95a7e0520839c1a48d98d141feca..9a5281bfed6fb4a1598df12a124a81cf61514e7c 100644 --- a/services/distributeddataservice/service/object/object_service_stub.cpp +++ b/services/distributeddataservice/service/object/object_service_stub.cpp @@ -21,6 +21,7 @@ #include "itypes_util.h" #include "log_print.h" +#include "utils/anonymous.h" namespace OHOS::DistributedObject { using namespace DistributedKv; @@ -32,17 +33,19 @@ int32_t ObjectServiceStub::ObjectStoreSaveOnRemote(MessageParcel &data, MessageP std::map> objectData; sptr obj; if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, deviceId, objectData, obj)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s deviceId:%{public}s objectData size:%{public}zu", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str(), + DistributedData::Anonymous::Change(deviceId).c_str(), objectData.size()); + return IPC_STUB_INVALID_DATA_ERR; } if (obj == nullptr) { ZLOGW("callback null"); return -1; } int32_t status = ObjectStoreSave(bundleName, sessionId, deviceId, objectData, obj); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("ObjectStoreSaveOnRemote fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -53,17 +56,18 @@ int32_t ObjectServiceStub::ObjectStoreRevokeSaveOnRemote(MessageParcel &data, Me std::string bundleName; sptr obj; if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, obj)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } if (obj == nullptr) { ZLOGW("callback null"); return -1; } int32_t status = ObjectStoreRevokeSave(bundleName, sessionId, obj); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("ObjectStoreRevokeSaveOnRemote fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -74,17 +78,18 @@ int32_t ObjectServiceStub::ObjectStoreRetrieveOnRemote(MessageParcel &data, Mess std::string bundleName; sptr obj; if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, obj)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } if (obj == nullptr) { ZLOGW("callback null"); return -1; } int32_t status = ObjectStoreRetrieve(bundleName, sessionId, obj); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("ObjectStoreRetrieveOnRemote fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -95,17 +100,18 @@ int32_t ObjectServiceStub::OnSubscribeRequest(MessageParcel &data, MessageParcel std::string bundleName; sptr obj; if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, obj)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } if (obj == nullptr) { ZLOGW("callback null"); return -1; } int32_t status = RegisterDataObserver(bundleName, sessionId, obj); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("OnSubscribeRequest fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } @@ -115,13 +121,14 @@ int32_t ObjectServiceStub::OnUnsubscribeRequest(MessageParcel &data, MessageParc std::string sessionId; std::string bundleName; if (!ITypesUtil::Unmarshal(data, bundleName, sessionId)) { - ZLOGW("read device list failed."); - return -1; + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = UnregisterDataChangeObserver(bundleName, sessionId); - if (!reply.WriteInt32(static_cast(status))) { - ZLOGE("OnSubscribeRequest fail %{public}d", static_cast(status)); - return -1; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } diff --git a/services/distributeddataservice/service/rdb/irdb_result_set.h b/services/distributeddataservice/service/rdb/irdb_result_set.h index c2e81993a4759d5f4db8699f8ac24c4095080110..5926784ca349d00e3617fc7f94068dfb254db5e8 100644 --- a/services/distributeddataservice/service/rdb/irdb_result_set.h +++ b/services/distributeddataservice/service/rdb/irdb_result_set.h @@ -17,10 +17,10 @@ #define DISTRIBUTED_RDB_IRDB_RESULT_SET_H #include "iremote_broker.h" -#include "result_set.h" +#include "remote_result_set.h" namespace OHOS::DistributedRdb { -class IRdbResultSet : public NativeRdb::ResultSet, public IRemoteBroker { +class IRdbResultSet : public NativeRdb::RemoteResultSet, public IRemoteBroker { public: using ColumnType = NativeRdb::ColumnType; virtual ~IRdbResultSet() = default; diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index 6f7eb43c7717c6889443758082ada79d65d409ed..ef578fd707027f0edbcc2e52e0bd134b9e29ee0e 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -68,11 +68,9 @@ void RdbServiceImpl::DeathRecipientImpl::OnRemoteDied(const wptr } } -RdbServiceImpl::RdbServiceImpl() - : timer_("SyncerTimer", -1), autoLaunchObserver_(this) +RdbServiceImpl::RdbServiceImpl() : autoLaunchObserver_(this) { ZLOGI("construct"); - timer_.Setup(); DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback( [this](const std::string& identifier, DistributedDB::AutoLaunchParam ¶m) { return ResolveAutoLaunch(identifier, param); @@ -126,7 +124,7 @@ void RdbServiceImpl::OnClientDied(pid_t pid) syncers_.ComputeIfPresent(pid, [this](const auto& key, StoreSyncersType& syncers) { syncerNum_ -= static_cast(syncers.size()); for (const auto& [name, syncer] : syncers) { - timer_.Unregister(syncer->GetTimerId()); + executors_->Remove(syncer->GetTimerId()); } return false; }); @@ -236,8 +234,10 @@ std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam &pa if (it != syncers.end()) { syncer = it->second; if (!param.isEncrypt_ || param.password_.empty()) { - timer_.Unregister(syncer->GetTimerId()); - uint32_t timerId = timer_.Register([this, syncer]() { SyncerTimeout(syncer); }, SYNCER_TIMEOUT, true); + executors_->Remove(syncer->GetTimerId(), true); + auto timerId = executors_->Schedule(std::chrono::milliseconds(SYNCER_TIMEOUT), [this, syncer] { + SyncerTimeout(syncer); + }); syncer->SetTimerId(timerId); return true; } @@ -262,7 +262,9 @@ std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam &pa syncers[storeId] = syncer_; syncer = syncer_; syncerNum_++; - uint32_t timerId = timer_.Register([this, syncer]() { SyncerTimeout(syncer); }, SYNCER_TIMEOUT, true); + auto timerId = executors_->Schedule(std::chrono::milliseconds(SYNCER_TIMEOUT), [this, syncer] { + SyncerTimeout(syncer); + }); syncer->SetTimerId(timerId); return !syncers.empty(); }); @@ -446,4 +448,9 @@ int32_t RdbServiceImpl::DestroyRDBTable(const RdbSyncerParam ¶m) delete syncer; return RDB_OK; } +int32_t RdbServiceImpl::OnExecutor(std::shared_ptr executors) +{ + executors_ = executors; + return 0; +} } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.h b/services/distributeddataservice/service/rdb/rdb_service_impl.h index 35f93b7c10ff0be9af32c292b39201bd17f49b0c..4a32c7128032c901259dd5a9e4b0dbf9b078c1b9 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -27,7 +27,6 @@ #include "rdb_notifier_proxy.h" #include "rdb_syncer.h" #include "store_observer.h" -#include "timer.h" #include "visibility.h" namespace OHOS::DistributedRdb { class API_EXPORT RdbServiceImpl : public RdbServiceStub { @@ -56,6 +55,8 @@ public: int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; + int32_t OnExecutor(std::shared_ptr executors) override; + protected: int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, const RdbPredicates& predicates, SyncResult& result) override; @@ -98,7 +99,6 @@ private: ConcurrentMap syncers_; ConcurrentMap> notifiers_; ConcurrentMap identifiers_; - Utils::Timer timer_; RdbStoreObserverImpl autoLaunchObserver_; static Factory factory_; @@ -108,6 +108,7 @@ private: static constexpr int32_t MAX_SYNCER_NUM = 50; static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms + std::shared_ptr executors_; }; } // namespace OHOS::DistributedRdb #endif diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index fc8a54726d85534da98269ed891fa1120e6f8d96..931792acf9baa426ff5499f90ed61809abf13919 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -19,6 +19,7 @@ #include #include "log_print.h" #include "itypes_util.h" +#include "utils/anonymous.h" namespace OHOS::DistributedRdb { int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, MessageParcel &reply) @@ -26,12 +27,16 @@ int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, std::string device; std::string table; if (!ITypesUtil::Unmarshal(data, device, table)) { - ZLOGE("read from message parcel failed"); - reply.WriteString(""); - return RDB_OK; + ZLOGE("Unmarshal device:%{public}s table:%{public}s", DistributedData::Anonymous::Change(device).c_str(), + table.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } - reply.WriteString(ObtainDistributedTableName(device, table)); + std::string distributedTableName = ObtainDistributedTableName(device, table); + if (!ITypesUtil::Marshal(reply, distributedTableName)) { + ZLOGE("Marshal distributedTableName:%{public}s", distributedTableName.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } return RDB_OK; } @@ -39,23 +44,16 @@ int32_t RdbServiceStub::OnRemoteInitNotifier(MessageParcel &data, MessageParcel { RdbSyncerParam param; sptr notifier; - if (!ITypesUtil::Unmarshal(data, param, notifier)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; - } - if (notifier == nullptr) { - ZLOGE("notifier is null"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; - } - if (InitNotifier(param, notifier) != RDB_OK) { - ZLOGE("init notifier failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; - } - ZLOGI("success"); - reply.WriteInt32(RDB_OK); + if (!ITypesUtil::Unmarshal(data, param, notifier) || notifier == nullptr) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + auto status = InitNotifier(param, notifier); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } return RDB_OK; } @@ -64,12 +62,16 @@ int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, Messag RdbSyncerParam param; std::vector tables; if (!ITypesUtil::Unmarshal(data, param, tables)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables size:%{public}zu", + param.bundleName_.c_str(), param.storeName_.c_str(), tables.size()); + return IPC_STUB_INVALID_DATA_ERR; } - reply.WriteInt32(SetDistributedTables(param, tables)); + auto status = SetDistributedTables(param, tables); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } return RDB_OK; } @@ -79,19 +81,16 @@ int32_t RdbServiceStub::OnRemoteDoSync(MessageParcel &data, MessageParcel &reply SyncOption option {}; RdbPredicates predicates; if (!ITypesUtil::Unmarshal(data, param, option, predicates)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str(), predicates.table_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } SyncResult result; - if (DoSync(param, option, predicates, result) != RDB_OK) { - reply.WriteInt32(RDB_ERROR); - return RDB_OK; - } - if (!ITypesUtil::Marshal(reply, result)) { - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + auto status = DoSync(param, option, predicates, result); + if (!ITypesUtil::Marshal(reply, status, result)) { + ZLOGE("Marshal status:0x%{public}x result size:%{public}zu", status, result.size()); + return IPC_STUB_WRITE_PARCEL_ERR; } return RDB_OK; } @@ -103,12 +102,16 @@ int32_t RdbServiceStub::OnRemoteDoAsync(MessageParcel &data, MessageParcel &repl SyncOption option {}; RdbPredicates predicates; if (!ITypesUtil::Unmarshal(data, param, seqNum, option, predicates)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s seqNum:%{public}u tables:%{public}s", + param.bundleName_.c_str(), param.storeName_.c_str(), seqNum, predicates.table_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } - reply.WriteInt32(DoAsync(param, seqNum, option, predicates)); + auto status = DoAsync(param, seqNum, option, predicates); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } return RDB_OK; } @@ -116,11 +119,16 @@ int32_t RdbServiceStub::OnRemoteDoSubscribe(MessageParcel &data, MessageParcel & { RdbSyncerParam param; if (!ITypesUtil::Unmarshal(data, param)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = DoSubscribe(param); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } - reply.WriteInt32(DoSubscribe(param)); return RDB_OK; } @@ -128,11 +136,16 @@ int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel { RdbSyncerParam param; if (!ITypesUtil::Unmarshal(data, param)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = DoUnSubscribe(param); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } - reply.WriteInt32(DoUnSubscribe(param)); return RDB_OK; } @@ -143,19 +156,19 @@ int32_t RdbServiceStub::OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel std::string sql; std::vector selectionArgs; if (!ITypesUtil::Unmarshal(data, param, device, sql, selectionArgs)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s device:%{public}s sql:%{public}s " + "selectionArgs size:%{public}zu", param.bundleName_.c_str(), param.storeName_.c_str(), + DistributedData::Anonymous::Change(device).c_str(), + DistributedData::Anonymous::Change(sql).c_str(), selectionArgs.size()); + return IPC_STUB_INVALID_DATA_ERR; } sptr resultSet; - int32_t status = RemoteQuery(param, device, sql, selectionArgs, resultSet); - if (status != RDB_OK) { - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + auto status = RemoteQuery(param, device, sql, selectionArgs, resultSet); + if (!ITypesUtil::Marshal(reply, status, resultSet)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } - reply.WriteInt32(RDB_OK); - reply.WriteRemoteObject(resultSet); return RDB_OK; } @@ -188,17 +201,18 @@ int32_t RdbServiceStub::OnRemoteDoCreateTable(MessageParcel &data, MessageParcel std::string writePermission; std::string readPermission; if (!ITypesUtil::Unmarshal(data, param, writePermission, readPermission)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s writePermission:%{public}s " + "readPermission:%{public}s", param.bundleName_.c_str(), param.storeName_.c_str(), + DistributedData::Anonymous::Change(writePermission).c_str(), + DistributedData::Anonymous::Change(readPermission).c_str()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = CreateRDBTable(param, writePermission, readPermission); - if (status != RDB_OK) { - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } - reply.WriteInt32(RDB_OK); return RDB_OK; } @@ -206,17 +220,16 @@ int32_t RdbServiceStub::OnRemoteDoDestroyTable(MessageParcel &data, MessageParce { RdbSyncerParam param; if (!ITypesUtil::Unmarshal(data, param)) { - ZLOGE("read from message parcel failed"); - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + param.storeName_.c_str()); + return IPC_STUB_INVALID_DATA_ERR; } int32_t status = DestroyRDBTable(param); - if (status != RDB_OK) { - reply.WriteInt32(RDB_ERROR); - return RDB_OK; + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; } - reply.WriteInt32(RDB_OK); return RDB_OK; } } // namespace OHOS::DistributedRdb diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/services/distributeddataservice/service/rdb/rdb_syncer.cpp index 1bd74d455409bfeaf4e6f6517f0b86e0dc0bac87..f8f6192a1b6c967ef960d8d5aedfad5d92775000 100644 --- a/services/distributeddataservice/service/rdb/rdb_syncer.cpp +++ b/services/distributeddataservice/service/rdb/rdb_syncer.cpp @@ -62,12 +62,12 @@ RdbSyncer::~RdbSyncer() noexcept } } -void RdbSyncer::SetTimerId(uint32_t timerId) +void RdbSyncer::SetTimerId(uint64_t timerId) { timerId_ = timerId; } -uint32_t RdbSyncer::GetTimerId() const +uint64_t RdbSyncer::GetTimerId() const { return timerId_; } @@ -109,9 +109,10 @@ int32_t RdbSyncer::Init( pid_ = pid; uid_ = uid; token_ = token; + StoreMetaData oldMeta; StoreMetaData meta; - if (CreateMetaData(meta) != RDB_OK) { + if (CreateMetaData(meta, oldMeta) != RDB_OK) { ZLOGE("create meta data failed"); return RDB_ERROR; } @@ -119,6 +120,11 @@ int32_t RdbSyncer::Init( ZLOGE("delegate is nullptr"); return RDB_ERROR; } + + if (oldMeta.storeType == RDB_DEVICE_COLLABORATION && oldMeta.version < StoreMetaData::UUID_CHANGED_TAG) { + delegate_->RemoveDeviceData(); + } + ZLOGI("success"); return RDB_OK; } @@ -150,10 +156,9 @@ void RdbSyncer::FillMetaData(StoreMetaData &meta) meta.isEncrypt = param_.isEncrypt_; } -int32_t RdbSyncer::CreateMetaData(StoreMetaData &meta) +int32_t RdbSyncer::CreateMetaData(StoreMetaData &meta, StoreMetaData &old) { FillMetaData(meta); - StoreMetaData old; bool isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old); if (isCreated && (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || old.area != meta.area)) { diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.h b/services/distributeddataservice/service/rdb/rdb_syncer.h index e049a864e218d6584ae00066261f4aba1f0cbbaa..42602bdbb83f3547ac249b955e11a853310866e0 100644 --- a/services/distributeddataservice/service/rdb/rdb_syncer.h +++ b/services/distributeddataservice/service/rdb/rdb_syncer.h @@ -39,9 +39,9 @@ public: pid_t GetPid() const; - void SetTimerId(uint32_t timerId); + void SetTimerId(uint64_t timerId); - uint32_t GetTimerId() const; + uint64_t GetTimerId() const; std::string GetStoreId() const; @@ -70,7 +70,7 @@ private: std::string GetAppId() const; - int32_t CreateMetaData(StoreMetaData &meta); + int32_t CreateMetaData(StoreMetaData &meta, StoreMetaData &old); void FillMetaData(StoreMetaData &meta); int32_t InitDBDelegate(const StoreMetaData &meta); bool SetSecretKey(const StoreMetaData &meta); @@ -85,7 +85,7 @@ private: pid_t pid_ {}; pid_t uid_ {}; uint32_t token_ {}; - uint32_t timerId_ {}; + uint64_t timerId_ {}; static std::vector GetConnectDevices(); static std::vector NetworkIdToUUID(const std::vector& networkIds); diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index f334bc90d43ba5ad96ecd1fe19367040d7a32d29..70ad6fddbf99bd05d4b6dbd047e361a6af889c04 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -29,7 +29,10 @@ config("module_private_config") { "../../framework/include/", ] - defines = [ "TEST_ON_DEVICE" ] + defines = [ + "TEST_ON_DEVICE", + "OPENSSL_SUPPRESS_DEPRECATED", + ] } ohos_unittest("ConfigFactoryTest") { diff --git a/services/distributeddataservice/service/test/config_factory_test.cpp b/services/distributeddataservice/service/test/config_factory_test.cpp index 6430fac49a239e8694df403b529cb632149f4093..70a6a5ad833c9303b948e0b4c40ae979dd2ec8da 100644 --- a/services/distributeddataservice/service/test/config_factory_test.cpp +++ b/services/distributeddataservice/service/test/config_factory_test.cpp @@ -61,7 +61,7 @@ HWTEST_F(ConfigFactoryTest, ComponentConfig, TestSize.Level0) { auto *components = ConfigFactory::GetInstance().GetComponentConfig(); ASSERT_NE(components, nullptr); - ASSERT_EQ(components->size(), 2); + ASSERT_EQ(components->size(), 3); const ComponentConfig &config = (*components)[0]; ASSERT_EQ(config.description, "3rd party adapter"); ASSERT_EQ(config.lib, "libconfigdemo.z.so"); @@ -69,7 +69,7 @@ HWTEST_F(ConfigFactoryTest, ComponentConfig, TestSize.Level0) ASSERT_EQ(config.destructor, ""); ASSERT_EQ(config.params, "{\"count\":1,\"key\":\"value\"}"); const ComponentConfig &cfg = (*components)[1]; - ASSERT_EQ(cfg.lib, "libconfigdemo2.z.so"); + ASSERT_EQ(cfg.lib, "libdistributedclouddata.z.so"); } /** diff --git a/services/distributeddataservice/service/test/mock/db_store_mock.cpp b/services/distributeddataservice/service/test/mock/db_store_mock.cpp index 9f7e36472871a3fc4a1840d2f2de8b5c03d321df..87639965c2b44870b3de0d12a3528b3a020bf1a4 100644 --- a/services/distributeddataservice/service/test/mock/db_store_mock.cpp +++ b/services/distributeddataservice/service/test/mock/db_store_mock.cpp @@ -305,5 +305,10 @@ DBStatus DBStoreMock::DeleteBatch(ConcurrentMap &store, const std::v }); return OK; } + +DBStatus DBStoreMock::UpdateKey(const UpdateKeyCallback &callback) +{ + return NOT_SUPPORT; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/db_store_mock.h b/services/distributeddataservice/service/test/mock/db_store_mock.h index eedd339a4a764acf1cd647bb61b3869ae4538f74..e50def98c4a8d00c89840247d92c8dd87b508343 100644 --- a/services/distributeddataservice/service/test/mock/db_store_mock.h +++ b/services/distributeddataservice/service/test/mock/db_store_mock.h @@ -36,6 +36,7 @@ public: using SecurityOption = DistributedDB::SecurityOption; using RemotePushFinishedNotifier = DistributedDB::RemotePushFinishedNotifier; using PushDataInterceptor = DistributedDB::PushDataInterceptor; + using UpdateKeyCallback = DistributedDB::UpdateKeyCallback; DBStatus Get(const Key &key, Value &value) const override; DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const override; DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const override; @@ -87,6 +88,7 @@ public: DBStatus RemoveDeviceData() override; DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const override; size_t GetSyncDataSize(const std::string &device) const override; + DBStatus UpdateKey(const UpdateKeyCallback &callback) override; private: static const uint32_t DEFAULT_SIZE = 0; diff --git a/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn b/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn index 57cdc6839f050e2c4d3e9f2cb73ac7be0e872fb6..d223694029b9c52221fc57e871e4275fc1a37772 100644 --- a/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn +++ b/services/distributeddataservice/test/fuzztest/schemaquery_fuzzer/BUILD.gn @@ -64,6 +64,7 @@ ohos_fuzztest("SchemaQueryFuzzTest") { "OMIT_FLATBUFFER", "RELATIONAL_STORE", "SQLITE_DISTRIBUTE_RELATIONAL", + "OPENSSL_SUPPRESS_DEPRECATED", ] external_deps = [ diff --git a/test/fuzztest/autolaunch_fuzzer/BUILD.gn b/test/fuzztest/autolaunch_fuzzer/BUILD.gn index 70d15988c946b1a414058576e39767fd86dead19..fb3e4402dca8637e48a9dc91c7ef701aa02b0a7a 100644 --- a/test/fuzztest/autolaunch_fuzzer/BUILD.gn +++ b/test/fuzztest/autolaunch_fuzzer/BUILD.gn @@ -78,6 +78,7 @@ ohos_fuzztest("AutoLaunchFuzzTest") { "OMIT_FLATBUFFER", "RELATIONAL_STORE", "SQLITE_DISTRIBUTE_RELATIONAL", + "OPENSSL_SUPPRESS_DEPRECATED", ] deps = [ diff --git a/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn b/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn index fd7b73abb30d29854e495d074a4d6d15003feee8..9ee8840fe0628534ba4f8cfba0ad1cba72e4b125 100644 --- a/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn +++ b/test/fuzztest/kvstoredisksize_fuzzer/BUILD.gn @@ -79,6 +79,7 @@ ohos_fuzztest("KvStoreDiskSizeFuzzTest") { "OMIT_FLATBUFFER", "RELATIONAL_STORE", "SQLITE_DISTRIBUTE_RELATIONAL", + "OPENSSL_SUPPRESS_DEPRECATED", ] deps = [