From 9729448dd634361a0431baddc0c95fb68b697a51 Mon Sep 17 00:00:00 2001 From: "1529367376@qq.com" Date: Wed, 13 Dec 2023 18:55:35 +0800 Subject: [PATCH 1/2] update Signed-off-by: 1529367376@qq.com --- bin/update/update.bat | 6 - data_object/CMakeLists.txt | 4 +- data_object/bundle.json | 6 +- data_object/data_object.gni | 2 + .../include/adaptor/client_adaptor.h | 2 +- .../include/adaptor/distributed_object_impl.h | 12 + .../adaptor/distributed_objectstore_impl.h | 12 +- .../include/adaptor/flat_object_store.h | 20 +- .../innerkitsimpl/include/common/bytes.h | 2 + .../include/communicator/dev_manager.h | 11 + ...uteddata_object_store_ipc_interface_code.h | 3 + .../innerkitsimpl/include/object_service.h | 6 + .../include/object_service_proxy.h | 5 + .../src/adaptor/distributed_object_impl.cpp | 179 +-- .../adaptor/distributed_object_store_impl.cpp | 50 +- .../src/adaptor/flat_object_store.cpp | 160 ++- .../src/communicator/dev_manager.cpp | 23 + .../src/object_service_proxy.cpp | 93 +- .../test/fuzztest/objectstore_fuzzer/BUILD.gn | 7 +- .../innerkitsimpl/test/unittest/BUILD.gn | 2 + .../test/unittest/src/object_store_test.cpp | 26 - .../include/adaptor/js_distributedobject.h | 1 + .../jskitsimpl/include/common/js_util.h | 81 ++ .../src/adaptor/js_distributedobject.cpp | 37 + .../jskitsimpl/src/common/js_util.cpp | 138 ++ data_object/interfaces/innerkits/BUILD.gn | 3 + .../interfaces/innerkits/distributed_object.h | 11 + data_object/interfaces/jskits/BUILD.gn | 2 + .../jskits/distributed_data_object.js | 105 +- datamgr_service/bundle.json | 4 + .../src/communication_strategy.cpp | 13 +- .../src/device_manager_adapter.cpp | 22 +- .../communicator/src/softbus_adapter.h | 14 +- .../src/softbus_adapter_standard.cpp | 167 ++- .../communicator/src/softbus_client.cpp | 165 +-- .../adapter/communicator/src/softbus_client.h | 19 +- .../communicator/communication_strategy.h | 6 +- .../communicator/device_manager_adapter.h | 5 + .../app/distributed_data.cfg | 3 +- .../app/src/installer/installer.cpp | 4 +- .../app/src/kvstore_meta_manager.cpp | 7 +- .../distributeddataservice/framework/BUILD.gn | 3 + .../framework/CMakeLists.txt | 1 + .../framework/cloud/schema_meta.cpp | 9 +- .../framework/include/cloud/sharing_center.h | 2 +- .../framework/include/error/general_error.h | 1 + .../framework/include/store/general_store.h | 5 + .../distributeddataservice/service/BUILD.gn | 15 +- .../service/CMakeLists.txt | 5 +- .../service/cloud/cloud_service_impl.cpp | 75 +- .../service/cloud/cloud_service_impl.h | 24 +- .../service/kvdb/store_cache.cpp | 3 + .../service/object/object_manager.cpp | 106 +- .../service/object/object_manager.h | 14 + .../service/object/object_service_impl.cpp | 68 + .../service/object/object_service_impl.h | 6 +- .../service/object/object_service_stub.cpp | 64 +- .../service/object/object_service_stub.h | 7 +- .../service/rdb/irdb_result_set.h | 3 +- .../service/rdb/rdb_asset_loader.cpp | 54 +- .../service/rdb/rdb_asset_loader.h | 10 +- .../service/rdb/rdb_cloud.cpp | 83 +- .../service/rdb/rdb_cloud.h | 13 +- .../service/rdb/rdb_cloud_data_translate.cpp | 1 + .../service/rdb/rdb_general_store.cpp | 48 +- .../service/rdb/rdb_general_store.h | 9 +- .../service/rdb/rdb_result_set_impl.cpp | 28 +- .../service/rdb/rdb_result_set_impl.h | 13 +- .../service/rdb/rdb_result_set_stub.cpp | 267 +--- .../service/rdb/rdb_result_set_stub.h | 56 +- .../service/rdb/rdb_service_impl.cpp | 107 +- .../service/rdb/rdb_service_impl.h | 13 +- .../service/rdb/rdb_service_stub.cpp | 10 +- .../service/test/BUILD.gn | 50 +- .../fuzztest/cloudservicestub_fuzzer/BUILD.gn | 4 +- .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 1 + .../objectservicestub_fuzzer/BUILD.gn | 9 + .../fuzztest/rdbresultsetstub_fuzzer/BUILD.gn | 4 +- .../rdbresultsetstub_fuzzer.cpp | 5 +- .../fuzztest/rdbservicestub_fuzzer/BUILD.gn | 4 +- .../service/test/mock/db_store_mock.cpp | 4 +- .../service/test/mock/general_store_mock.cpp | 40 +- .../service/test/mock/general_store_mock.h | 3 + .../service/test/value_proxy_test.cpp | 2 +- .../service/udmf/udmf_service_impl.cpp | 22 + .../service/udmf/udmf_service_impl.h | 1 + .../service/udmf/utd/custom_utd_installer.cpp | 98 +- .../service/udmf/utd/custom_utd_installer.h | 5 +- ...application.DataShareExtensionAbility.d.ts | 5 + .../api/@ohos.data.DataShareResultSet.d.ts | 5 + .../api/@ohos.data.ValuesBucket.d.ts | 5 + interface_sdk/api/@ohos.data.cloudData.d.ts | 869 ++++++++++++- .../api/@ohos.data.cloudExtension.d.ts | 1130 ++--------------- interface_sdk/api/@ohos.data.dataAbility.d.ts | 5 + interface_sdk/api/@ohos.data.dataShare.d.ts | 5 + .../api/@ohos.data.dataSharePredicates.d.ts | 5 + .../api/@ohos.data.distributedData.d.ts | 5 + .../api/@ohos.data.distributedDataObject.d.ts | 87 ++ .../api/@ohos.data.distributedKVStore.d.ts | 5 + interface_sdk/api/@ohos.data.preferences.d.ts | 21 + interface_sdk/api/@ohos.data.rdb.d.ts | 5 + .../api/@ohos.data.relationalStore.d.ts | 115 +- interface_sdk/api/@ohos.data.storage.d.ts | 7 + .../api/@ohos.data.unifiedDataChannel.d.ts | 5 + .../api/@ohos.data.uniformTypeDescriptor.d.ts | 5 + kv_store/bundle.json | 1 + kv_store/frameworks/common/itypes_util.h | 10 + .../include/js_kv_store_resultset.h | 8 +- .../src/js_device_kv_store.cpp | 6 +- .../distributeddata/src/js_kv_store.cpp | 2 + .../src/js_kv_store_resultset.cpp | 37 +- .../src/js_single_kv_store.cpp | 6 +- .../include/js_kv_store_resultset.h | 6 +- .../src/js_device_kv_store.cpp | 2 +- .../src/js_kv_store_resultset.cpp | 37 +- .../src/js_single_kv_store.cpp | 5 +- .../frameworks/libs/distributeddb/BUILD.gn | 4 + .../common/include/auto_launch.h | 7 + .../common/include/cloud/cloud_db_constant.h | 2 + .../distributeddb/common/include/db_common.h | 4 + .../common/include/db_constant.h | 1 + .../common/include/db_dfx_adapter.h | 2 +- .../distributeddb/common/include/db_errno.h | 2 + .../common/include/relational/table_info.h | 2 + .../distributeddb/common/src/auto_launch.cpp | 361 ++++-- .../distributeddb/common/src/db_common.cpp | 21 + .../common/src/db_dfx_adapter.cpp | 4 +- .../common/src/query_expression.cpp | 17 + .../common/src/relational/table_info.cpp | 8 + .../include/communicator_aggregator.h | 11 + .../include/send_task_scheduler.h | 3 + .../src/communicator_aggregator.cpp | 67 +- .../communicator/src/network_adapter.cpp | 6 +- .../communicator/src/send_task_scheduler.cpp | 15 + .../libs/distributeddb/distributeddb.gni | 1 + .../include/grd_base/grd_type_export.h | 7 + .../gaussdb_rd/include/grd_kv/grd_kv_api.h | 7 + .../src/common/include/grd_api_manager.h | 7 + .../src/common/src/grd_api_manager.cpp | 6 + .../gaussdb_rd/src/common/src/os_api.cpp | 14 +- .../src/executor/base/grd_db_api.cpp | 20 + .../src/executor/base/grd_db_api_inner.cpp | 2 +- .../src/executor/document/check_common.h | 1 - .../executor/document/grd_document_api.cpp | 28 + .../document/grd_document_api_inner.cpp | 2 +- .../executor/document/grd_resultset_api.cpp | 24 + .../document/grd_resultset_api_inner.cpp | 7 +- .../src/executor/include/grd_kv_api_inner.h | 7 + .../gaussdb_rd/src/executor/kv/grd_kv_api.cpp | 64 + .../src/executor/kv/grd_kv_api_inner.cpp | 39 +- .../src/interface/src/document_key.cpp | 4 +- .../distributeddb/include/query_expression.h | 1 + .../include/cloud/cloud_store_types.h | 6 +- .../relational/relational_store_delegate.h | 4 +- .../interfaces/include/store_types.h | 2 + .../src/kv_store_delegate_manager.cpp | 3 +- .../interfaces/src/kv_store_errno.cpp | 2 + .../src/kv_store_nb_delegate_impl.cpp | 4 +- .../relational_store_delegate_impl.cpp | 5 +- .../relational_store_delegate_impl.h | 4 +- .../relational_store_sqlite_ext.cpp | 3 +- .../relational/relational_sync_able_storage.h | 34 + .../include/icloud_sync_storage_interface.h | 11 + .../storage/include/storage_proxy.h | 4 + .../storage/src/data_transformer.h | 5 +- .../rd_single_ver_natural_store.cpp | 9 +- .../gaussdb_rd/rd_single_ver_natural_store.h | 2 + ...rd_single_ver_natural_store_connection.cpp | 32 +- .../gaussdb_rd/rd_single_ver_result_set.cpp | 97 +- .../src/gaussdb_rd/rd_single_ver_result_set.h | 12 +- .../rd_single_ver_storage_engine.cpp | 18 +- .../rd_single_ver_storage_executor.cpp | 135 +- .../rd_single_ver_storage_executor.h | 23 +- .../storage/src/gaussdb_rd/rd_utils.cpp | 55 +- .../storage/src/gaussdb_rd/rd_utils.h | 5 +- .../src/relational_sync_able_storage.cpp | 442 ++++++- .../sqlite_relational_database_upgrader.cpp | 29 +- .../relational/sqlite_relational_store.cpp | 130 +- .../relational/sqlite_relational_store.h | 9 +- ...qlite_single_relational_storage_engine.cpp | 10 +- .../sqlite_single_relational_storage_engine.h | 4 +- .../sqlite_single_ver_database_upgrader.cpp | 4 - .../sqlite_single_ver_natural_store.cpp | 6 +- ...te_single_ver_natural_store_connection.cpp | 36 +- ...single_ver_relational_storage_executor.cpp | 49 +- ...e_single_ver_relational_storage_executor.h | 38 +- ...ver_relational_storage_extend_executor.cpp | 173 ++- .../storage/src/storage_proxy.cpp | 18 + .../syncer/src/cloud/cloud_db_proxy.cpp | 7 +- .../syncer/src/cloud/cloud_sync_utils.cpp | 9 +- .../syncer/src/cloud/cloud_syncer.cpp | 51 +- .../syncer/src/cloud/cloud_syncer.h | 20 +- .../syncer/src/cloud/cloud_syncer_extend.cpp | 67 +- .../libs/distributeddb/test/BUILD.gn | 62 +- .../common/distributeddb_tools_unit_test.cpp | 7 +- .../common/distributeddb_tools_unit_test.h | 3 +- ...b_cloud_interfaces_relational_ext_test.cpp | 125 ++ ...cloud_interfaces_set_cloud_schema_test.cpp | 4 +- ...ddb_interfaces_database_rd_kernel_test.cpp | 31 +- ..._interfaces_nb_delegate_test_rd_kernal.cpp | 4 - ...terfaces_relational_tracker_table_test.cpp | 11 + ...teddb_cloud_assets_operation_sync_test.cpp | 76 +- ...eddb_storage_rd_register_observer_test.cpp | 1 - ...ge_rd_single_ver_natural_executor_test.cpp | 5 - ...e_rd_single_ver_natural_store_testcase.cpp | 9 - ...rage_rd_single_ver_storage_engine_test.cpp | 4 - ...eddb_cloud_syncer_download_assets_test.cpp | 1 - .../syncer/cloud/virtual_asset_loader.cpp | 2 +- .../syncer/cloud/virtual_asset_loader.h | 2 +- .../common/syncer/cloud/virtual_cloud_db.cpp | 11 + .../common/syncer/cloud/virtual_cloud_db.h | 3 + ...ddb_single_ver_p2p_subscribe_sync_test.cpp | 25 + .../distributeddata/include/executor.h | 2 +- mock/CMakeLists.txt | 4 +- mock/src/mock_dfs_service.cpp | 36 +- relational_store/CMakeLists.txt | 15 +- relational_store/bundle.json | 16 +- .../js/napi/cloud_data/src/js_cloud_share.cpp | 16 +- .../js/napi/cloud_data/src/js_cloud_utils.cpp | 22 +- .../cloud_data/src/js_const_properties.cpp | 3 + .../napi/cloud_extension/cloud_extension.cpp | 3 +- .../cloud_sharing_types_util.js | 269 ++-- .../frameworks/js/napi/rdb/BUILD.gn | 2 + .../js/napi/rdb/include/napi_result_set.h | 4 +- .../napi/rdb/mock/include/napi_result_set.h | 5 +- .../js/napi/rdb/src/napi_result_set.cpp | 118 +- .../js/napi/relationalstore/BUILD.gn | 5 + .../mock/include/napi_result_set.h | 5 +- .../relationalstore/src/napi_rdb_store.cpp | 14 +- .../src/napi_rdb_store_helper.cpp | 16 +- .../cloud_data/src/cloud_types_util.cpp | 4 +- .../native/rdb/include/rdb_service_proxy.h | 6 +- .../native/rdb/src/cache_result_set.cpp | 13 +- .../native/rdb/src/rdb_service_proxy.cpp | 34 +- .../native/rdb/src/rdb_store_impl.cpp | 18 +- .../native/rdb/src/result_set_proxy.cpp | 73 +- .../native/rdb/src/sqlite_global_config.cpp | 3 + .../cloud_data/include/cloud_types.h | 2 + .../inner_api/rdb/include/rdb_service.h | 12 +- .../inner_api/rdb/include/remote_result_set.h | 2 +- .../unittest/src/RdbstoreCustomDir.test.js | 101 +- test/CMakeLists.txt | 3 + 242 files changed, 5731 insertions(+), 3053 deletions(-) diff --git a/bin/update/update.bat b/bin/update/update.bat index cab95e31..ac060ee0 100644 --- a/bin/update/update.bat +++ b/bin/update/update.bat @@ -14,12 +14,6 @@ git clone https://gitee.com/openharmony/distributeddatamgr_kv_store.git ./tmp/kv git clone https://gitee.com/openharmony/distributeddatamgr_relational_store.git ./tmp/relational_store @echo "clone the data_object" git clone https://gitee.com/openharmony/distributeddatamgr_data_object.git ./tmp/data_object -@echo "clone the data_share" -git clone https://gitee.com/openharmony/distributeddatamgr_data_share.git ./tmp/data_share -@echo "clone the preferences" -git clone https://gitee.com/openharmony/distributeddatamgr_preferences.git ./tmp/preferences -@echo "clone the udmf" -git clone https://gitee.com/openharmony/distributeddatamgr_udmf.git ./tmp/udmf xcopy tmp\* ..\..\ /y /e /i /q diff --git a/data_object/CMakeLists.txt b/data_object/CMakeLists.txt index d5fc6969..37328408 100644 --- a/data_object/CMakeLists.txt +++ b/data_object/CMakeLists.txt @@ -10,6 +10,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") set(MOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../mock) set(KV_STORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../kv_store) +set(RELATIONAL_STORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../relational_store) + add_definitions(-DNAPI_EXPERIMENTAL) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/src data_object_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/src/adaptor data_object_src) @@ -31,7 +33,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/safwk/native/inc include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) -set(links secure mock adapter distributeddb kvdb) +set(links secure mock adapter distributeddb kvdb common_type) add_library(data_object SHARED ${data_object_src}) target_link_libraries(data_object ${links}) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/innerkits) \ No newline at end of file diff --git a/data_object/bundle.json b/data_object/bundle.json index 215ff8d1..51c2b4b2 100644 --- a/data_object/bundle.json +++ b/data_object/bundle.json @@ -55,7 +55,8 @@ "c_utils", "device_manager", "kv_store", - "common_event_service" + "common_event_service", + "relational_store" ], "third_party": [ "libuv", @@ -73,7 +74,8 @@ "header_files": [ "distributed_object.h", "distributed_objectstore.h", - "objectstore_errors.h" + "objectstore_errors.h", + "object_types.h" ], "header_base": "//foundation/distributeddatamgr/data_object/interfaces/innerkits" } diff --git a/data_object/data_object.gni b/data_object/data_object.gni index 34155d9a..d3b7d9f4 100644 --- a/data_object/data_object.gni +++ b/data_object/data_object.gni @@ -12,3 +12,5 @@ # limitations under the License. kvstore_path = "//foundation/distributeddatamgr/kv_store/frameworks" + +data_object_base_path = "//foundation/distributeddatamgr/data_object" diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h b/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h index b1d3eb58..ce1012f3 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/client_adaptor.h @@ -33,7 +33,7 @@ private: static std::shared_ptr GetDistributedDataManager(); }; -class ObjectStoreDataServiceProxy : public IRemoteProxy { +class ObjectStoreDataServiceProxy : public IRemoteProxy { public: explicit ObjectStoreDataServiceProxy(const sptr &impl); ~ObjectStoreDataServiceProxy() = default; diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_object_impl.h b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_object_impl.h index ad213765..16fc6bf0 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_object_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_object_impl.h @@ -37,11 +37,23 @@ public: uint32_t Save(const std::string &deviceId) override; uint32_t RevokeSave() override; uint32_t GetType(const std::string &key, Type &type) override; + uint32_t BindAssetStore(const std::string &assetKey, AssetBindInfo &bindInfo) override; private: + uint32_t GetAssetValue(const std::string &assetKey, Asset &assetValue); std::string sessionId_; FlatObjectStore *flatObjectStore_ = nullptr; + uint32_t PutDeviceId(); + void RemovePrefix(Asset &assetValue); }; + +#define LOG_ERROR_RETURN(condition, message, retVal) \ + do { \ + if (!(condition)) { \ + LOG_ERROR("test (" #condition ") failed: " message); \ + return retVal; \ + } \ + } while (0) } // namespace OHOS::ObjectStore #endif // DISTRIBUTED_OBJECT_IMPL_H diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h index b8007465..04a73387 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h @@ -64,12 +64,16 @@ private: }; class WatcherProxy : public FlatObjectWatcher { public: - WatcherProxy(const std::shared_ptr objectWatcher, const std::string &sessionId); - void OnChanged(const std::string &sessionid, const std::vector &changedData) override; + using AssetChangeCallback = std::function watcher)>; + WatcherProxy(const std::shared_ptr objectWatcher, const std::string &sessionId); + void OnChanged(const std::string &sessionId, const std::vector &changedData) override; + void SetAssetChangeCallBack(const AssetChangeCallback &assetChangeCallback); private: + bool FindChangedAssetKey(const std::string &changedKey, std::string &assetKey); std::shared_ptr objectWatcher_; + AssetChangeCallback assetChangeCallback_; }; } // namespace OHOS::ObjectStore - -#endif // DISTRIBUTED_OBJECTSTORE_H +#endif // DISTRIBUTED_OBJECTSTORE_IMPL_H diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h index 5e8e7359..4ed9b687 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h @@ -22,6 +22,8 @@ #include "bytes.h" #include "flat_object_storage_engine.h" #include "condition_lock.h" +#include "distributed_object.h" +#include "object_types.h" namespace OHOS::ObjectStore { class FlatObjectWatcher : public TableWatcher { @@ -43,6 +45,7 @@ public: int32_t SubscribeDataChange(const std::string &bundleName, const std::string &sessionId, std::function> &data)> &callback); int32_t UnregisterDataChange(const std::string &bundleName, const std::string &sessionId); + int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId); private: int32_t SaveObject(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const std::map> &objectData, @@ -56,12 +59,11 @@ class FlatObjectStore { public: explicit FlatObjectStore(const std::string &bundleName); ~FlatObjectStore(); + std::string GetBundleName(); uint32_t CreateObject(const std::string &sessionId); uint32_t Delete(const std::string &objectId); uint32_t Watch(const std::string &objectId, std::shared_ptr watcher); uint32_t UnWatch(const std::string &objectId); - uint32_t Put(const std::string &sessionId, const std::string &key, std::vector value); - uint32_t Get(std::string &sessionId, const std::string &key, Bytes &value); uint32_t SetStatusNotifier(std::shared_ptr sharedPtr); uint32_t SyncAllData(const std::string &sessionId, const std::function &)> &onComplete); @@ -70,8 +72,20 @@ public: void CheckRetrieveCache(const std::string &sessionId); void FilterData(const std::string &sessionId, std::map> &data); - + uint32_t PutDouble(const std::string &sessionId, const std::string &key, double value); + uint32_t PutBoolean(const std::string &sessionId, const std::string &key, bool value); + uint32_t PutString(const std::string &sessionId, const std::string &key, const std::string &value); + uint32_t PutComplex(const std::string &sessionId, const std::string &key, const std::vector &value); + uint32_t GetDouble(const std::string &sessionId, const std::string &key, double &value); + uint32_t GetBoolean(const std::string &sessionId, const std::string &key, bool &value); + uint32_t GetString(const std::string &sessionId, const std::string &key, std::string &value); + uint32_t GetComplex(const std::string &sessionId, const std::string &key, std::vector &value); + uint32_t GetType(const std::string &sessionId, const std::string &key, Type &type); + uint32_t BindAssetStore(const std::string &sessionId, AssetBindInfo &bindInfo, Asset &assetValue); private: + uint32_t Put(const std::string &sessionId, const std::string &key, std::vector value); + uint32_t Get(const std::string &sessionId, const std::string &key, Bytes &value); + std::shared_ptr storageEngine_; CacheManager *cacheManager_; std::mutex mutex_; diff --git a/data_object/frameworks/innerkitsimpl/include/common/bytes.h b/data_object/frameworks/innerkitsimpl/include/common/bytes.h index 11f94903..5558bf14 100644 --- a/data_object/frameworks/innerkitsimpl/include/common/bytes.h +++ b/data_object/frameworks/innerkitsimpl/include/common/bytes.h @@ -23,6 +23,8 @@ namespace OHOS::ObjectStore { using Bytes = std::vector; static const char *FIELDS_PREFIX = "p_"; static const int32_t FIELDS_PREFIX_LEN = 2; +static const std::string STRING_PREFIX = "[STRING]"; +static const int32_t STRING_PREFIX_LEN = STRING_PREFIX.length(); } // namespace OHOS::ObjectStore #endif // BYTES_H diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/dev_manager.h b/data_object/frameworks/innerkitsimpl/include/communicator/dev_manager.h index d9376ece..02c62ec7 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/dev_manager.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/dev_manager.h @@ -16,10 +16,17 @@ #define DATA_OBJECT_DEV_MANAGER_H #include #include +#include namespace OHOS { namespace ObjectStore { class DevManager { public: + struct DetailInfo { + std::string uuid; + std::string networkId; + std::string deviceName; + std::string deviceType; + }; static DevManager *GetInstance() { static DevManager *instance = new DevManager(); @@ -27,11 +34,15 @@ public: } void RegisterDevCallback(); std::string GetUuidByNodeId(const std::string &nodeId) const; + const DetailInfo &GetLocalDevice(); private: DevManager(); ~DevManager(); int32_t Init(); + const DetailInfo invalidDetail_{}; + DetailInfo localInfo_{}; + mutable std::mutex mutex_{}; }; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h b/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h index 143334b7..d1728569 100644 --- a/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h +++ b/data_object/frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h @@ -26,6 +26,9 @@ enum class ObjectServiceInterfaceCode { OBJECTSTORE_RETRIEVE, OBJECTSTORE_REGISTER_OBSERVER, OBJECTSTORE_UNREGISTER_OBSERVER, + OBJECTSTORE_ON_ASSET_CHANGED, + OBJECTSTORE_BIND_ASSET_STORE, + OBJECTSTORE_DELETE_SNAPSHOT, OBJECTSTORE_SERVICE_CMD_MAX }; diff --git a/data_object/frameworks/innerkitsimpl/include/object_service.h b/data_object/frameworks/innerkitsimpl/include/object_service.h index 2e49a85f..37ea3754 100644 --- a/data_object/frameworks/innerkitsimpl/include/object_service.h +++ b/data_object/frameworks/innerkitsimpl/include/object_service.h @@ -20,6 +20,7 @@ #include #include #include "distributeddata_object_store_ipc_interface_code.h" +#include "object_types.h" namespace OHOS::DistributedObject { class ObjectService { @@ -34,6 +35,11 @@ public: virtual int32_t RegisterDataObserver( const std::string &bundleName, const std::string &sessionId, sptr callback) = 0; virtual int32_t UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId) = 0; + virtual int32_t OnAssetChanged(const std::string &bundleName, const std::string &sessionId, + const std::string &deviceId, const ObjectStore::Asset &assetValue) = 0; + virtual int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, + ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) = 0; + virtual int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) = 0; }; } // namespace OHOS::DistributedObject #endif diff --git a/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h b/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h index 786034ee..a6b2c271 100644 --- a/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h +++ b/data_object/frameworks/innerkitsimpl/include/object_service_proxy.h @@ -37,6 +37,11 @@ public: sptr callback) override; int32_t UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId) override; + int32_t OnAssetChanged(const std::string &bundleName, const std::string &sessionId, + const std::string &deviceId, const ObjectStore::Asset &assetValue) override; + int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, + ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) override; + int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) override; private: static inline BrokerDelegator delegator_; }; diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp index e3c247fc..833cd059 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp @@ -18,134 +18,53 @@ #include "hitrace.h" #include "objectstore_errors.h" #include "string_utils.h" +#include "dev_manager.h" +#include "bytes_utils.h" namespace OHOS::ObjectStore { DistributedObjectImpl::~DistributedObjectImpl() { } -void PutNum(void *val, uint32_t offset, uint32_t valLen, Bytes &data) -{ - uint32_t len = valLen + offset; - if (len > sizeof(data.front()) * data.size()) { - data.resize(len); - } - - for (uint32_t i = 0; i < valLen; i++) { - // 8 bit = 1 byte - data[offset + i] = *(static_cast(val)) >> ((valLen - i - 1) * 8); - } -} - -uint32_t GetNum(Bytes &data, uint32_t offset, void *val, uint32_t valLen) -{ - uint8_t *value = static_cast(val); - uint32_t len = offset + valLen; - uint32_t dataLen = data.size(); - if (dataLen < len) { - LOG_ERROR("DistributedObjectImpl:GetNum data.size() %{public}d, offset %{public}d, valLen %{public}d", dataLen, - offset, valLen); - return ERR_DATA_LEN; - } - for (uint32_t i = 0; i < valLen; i++) { - value[i] = data[len - 1 - i]; - } - return SUCCESS; -} - uint32_t DistributedObjectImpl::PutDouble(const std::string &key, double value) { DataObjectHiTrace trace("DistributedObjectImpl::PutDouble"); - Bytes data; - Type type = Type::TYPE_DOUBLE; - PutNum(&type, 0, sizeof(type), data); - PutNum(&value, sizeof(type), sizeof(value), data); - return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); + return flatObjectStore_->PutDouble(sessionId_, key, value); } uint32_t DistributedObjectImpl::PutBoolean(const std::string &key, bool value) { DataObjectHiTrace trace("DistributedObjectImpl::PutBoolean"); - Bytes data; - Type type = Type::TYPE_BOOLEAN; - PutNum(&type, 0, sizeof(type), data); - PutNum(&value, sizeof(type), sizeof(value), data); - return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); + return flatObjectStore_->PutBoolean(sessionId_, key, value); } uint32_t DistributedObjectImpl::PutString(const std::string &key, const std::string &value) { DataObjectHiTrace trace("DistributedObjectImpl::PutString"); - Bytes data; - Type type = Type::TYPE_STRING; - PutNum(&type, 0, sizeof(type), data); - Bytes dst = StringUtils::StrToBytes(value); - data.insert(data.end(), dst.begin(), dst.end()); - return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); + if (key.find(ASSET_DOT) != std::string::npos) { + PutDeviceId(); + } + return flatObjectStore_->PutString(sessionId_, key, value); } uint32_t DistributedObjectImpl::GetDouble(const std::string &key, double &value) { - Bytes data; - Bytes keyBytes = StringUtils::StrToBytes(key); - uint32_t status = flatObjectStore_->Get(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl:GetDouble field not exist. %{public}d %{public}s", status, key.c_str()); - return status; - } - status = GetNum(data, sizeof(Type), &value, sizeof(value)); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::GetDouble getNum err. %{public}d", status); - } - return status; + return flatObjectStore_->GetDouble(sessionId_, key, value); } uint32_t DistributedObjectImpl::GetBoolean(const std::string &key, bool &value) { - Bytes data; - Bytes keyBytes = StringUtils::StrToBytes(key); - uint32_t status = flatObjectStore_->Get(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl:GetBoolean field not exist. %{public}d %{public}s", status, key.c_str()); - return status; - } - status = GetNum(data, sizeof(Type), &value, sizeof(value)); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::GetBoolean getNum err. %{public}d", status); - return status; - } - return SUCCESS; + return flatObjectStore_->GetBoolean(sessionId_, key, value); } uint32_t DistributedObjectImpl::GetString(const std::string &key, std::string &value) { - Bytes data; - uint32_t status = flatObjectStore_->Get(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl:GetString field not exist. %{public}d %{public}s", status, key.c_str()); - return status; - } - status = StringUtils::BytesToStrWithType(data, value); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::GetString dataToVal err. %{public}d", status); - } - return status; + return flatObjectStore_->GetString(sessionId_, key, value); } uint32_t DistributedObjectImpl::GetType(const std::string &key, Type &type) { - Bytes data; - uint32_t status = flatObjectStore_->Get(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl:GetString field not exist. %{public}d %{public}s", status, key.c_str()); - return status; - } - status = GetNum(data, 0, &type, sizeof(type)); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::GetBoolean getNum err. %{public}d", status); - return status; - } - return SUCCESS; + return flatObjectStore_->GetType(sessionId_, key, type); } std::string &DistributedObjectImpl::GetSessionId() @@ -161,26 +80,12 @@ DistributedObjectImpl::DistributedObjectImpl(const std::string &sessionId, FlatO uint32_t DistributedObjectImpl::PutComplex(const std::string &key, const std::vector &value) { DataObjectHiTrace trace("DistributedObjectImpl::PutComplex"); - Bytes data; - Type type = Type::TYPE_COMPLEX; - PutNum(&type, 0, sizeof(type), data); - data.insert(data.end(), value.begin(), value.end()); - uint32_t status = flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::PutBoolean setField err %{public}d", status); - } - return status; + return flatObjectStore_->PutComplex(sessionId_, key, value); } uint32_t DistributedObjectImpl::GetComplex(const std::string &key, std::vector &value) { - uint32_t status = flatObjectStore_->Get(sessionId_, FIELDS_PREFIX + key, value); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl:GetString field not exist. %{public}d %{public}s", status, key.c_str()); - return status; - } - value.erase(value.begin(), value.begin() + sizeof(Type)); - return status; + return flatObjectStore_->GetComplex(sessionId_, key, value); } uint32_t DistributedObjectImpl::Save(const std::string &deviceId) @@ -202,4 +107,60 @@ uint32_t DistributedObjectImpl::RevokeSave() } return status; } + +uint32_t DistributedObjectImpl::PutDeviceId() +{ + DevManager::DetailInfo detailInfo = DevManager::GetInstance()->GetLocalDevice(); + return flatObjectStore_->PutString(sessionId_, DEVICEID_KEY, detailInfo.networkId); +} + +uint32_t DistributedObjectImpl::GetAssetValue(const std::string &assetKey, Asset &assetValue) +{ + double assetStatus = 0.0; + auto status = GetDouble(assetKey + STATUS_SUFFIX, assetStatus); + if (status == SUCCESS) { + assetValue.status = static_cast(assetStatus); + } + status = GetString(assetKey + NAME_SUFFIX, assetValue.name); + LOG_ERROR_RETURN(status == SUCCESS, "get name failed!", status); + status = GetString(assetKey + URI_SUFFIX, assetValue.uri); + LOG_ERROR_RETURN(status == SUCCESS, "get uri failed!", status); + status = GetString(assetKey + PATH_SUFFIX, assetValue.path); + LOG_ERROR_RETURN(status == SUCCESS, "get path failed!", status); + status = GetString(assetKey + CREATE_TIME_SUFFIX, assetValue.createTime); + LOG_ERROR_RETURN(status == SUCCESS, "get createTime failed!", status); + status = GetString(assetKey + MODIFY_TIME_SUFFIX, assetValue.modifyTime); + LOG_ERROR_RETURN(status == SUCCESS, "get modifyTime failed!", status); + status = GetString(assetKey + SIZE_SUFFIX, assetValue.size); + LOG_ERROR_RETURN(status == SUCCESS, "get size failed!", status); + RemovePrefix(assetValue); + return status; +} + +void DistributedObjectImpl::RemovePrefix(Asset &assetValue) +{ + assetValue.name = assetValue.name.substr(STRING_PREFIX_LEN); + assetValue.uri = assetValue.uri.substr(STRING_PREFIX_LEN); + assetValue.path = assetValue.path.substr(STRING_PREFIX_LEN); + assetValue.createTime = assetValue.createTime.substr(STRING_PREFIX_LEN); + assetValue.modifyTime = assetValue.modifyTime.substr(STRING_PREFIX_LEN); + assetValue.size = assetValue.size.substr(STRING_PREFIX_LEN); + assetValue.hash = assetValue.modifyTime + "_" + assetValue.size; +} + +uint32_t DistributedObjectImpl::BindAssetStore(const std::string &assetKey, AssetBindInfo &bindInfo) +{ + Asset assetValue; + auto status = GetAssetValue(assetKey, assetValue); + if (status != SUCCESS) { + LOG_ERROR("DistributedObjectImpl:GetAssetValue failed. status = %{public}d", status); + return status; + } + status = flatObjectStore_->BindAssetStore(sessionId_, bindInfo, assetValue); + if (status != SUCCESS) { + LOG_ERROR("DistributedObjectImpl:BindAssetStore failed. status = %{public}d", status); + return status; + } + return status; +} } // namespace OHOS::ObjectStore \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp index 7929938d..bee691ed 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp @@ -14,6 +14,7 @@ */ #include +#include #include "hitrace.h" #include "distributed_object_impl.h" @@ -21,6 +22,7 @@ #include "objectstore_errors.h" #include "softbus_adapter.h" #include "string_utils.h" +#include "asset_change_timer.h" namespace OHOS::ObjectStore { DistributedObjectStoreImpl::DistributedObjectStoreImpl(FlatObjectStore *flatObjectStore) @@ -89,7 +91,7 @@ DistributedObject *DistributedObjectStoreImpl::CreateObject(const std::string &s status = ERR_NULL_OBJECTSTORE; return nullptr; } - + if (sessionId.empty()) { LOG_ERROR("DistributedObjectStoreImpl::CreateObject Invalid sessionId"); status = ERR_INVALID_ARGS; @@ -150,6 +152,11 @@ uint32_t DistributedObjectStoreImpl::Watch(DistributedObject *object, std::share return ERR_EXIST; } std::shared_ptr watcherProxy = std::make_shared(watcher, object->GetSessionId()); + watcherProxy->SetAssetChangeCallBack( + [=](const std::string &sessionId, const std::string &assetKey, std::shared_ptr objectWatcher) { + AssetChangeTimer *assetChangeTimer = AssetChangeTimer::GetInstance(flatObjectStore_, objectWatcher); + assetChangeTimer->OnAssetChanged(sessionId, assetKey); + }); uint32_t status = flatObjectStore_->Watch(object->GetSessionId(), watcherProxy); if (status != SUCCESS) { LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status); @@ -201,9 +208,46 @@ WatcherProxy::WatcherProxy(const std::shared_ptr objectWatcher, c { } -void WatcherProxy::OnChanged(const std::string &sessionid, const std::vector &changedData) +void WatcherProxy::OnChanged(const std::string &sessionId, const std::vector &changedData) +{ + std::unordered_set assetKeys; + std::vector otherKeys; + for (const auto &str : changedData) { + if (str.find(ASSET_DOT) == std::string::npos) { + if (str != DEVICEID_KEY) { + otherKeys.push_back(str); + } + } else { + std::string assetKey; + if (FindChangedAssetKey(str, assetKey)) { + assetKeys.insert(assetKey); + } + } + } + if (!otherKeys.empty()) { + objectWatcher_->OnChanged(sessionId, otherKeys); + } + if (assetChangeCallback_ != nullptr && !assetKeys.empty()) { + for (auto &assetKey : assetKeys) { + assetChangeCallback_(sessionId, assetKey, objectWatcher_); + } + } +} + +bool WatcherProxy::FindChangedAssetKey(const std::string &changedKey, std::string &assetKey) +{ + std::size_t dotPos = changedKey.find(ASSET_DOT); + if ((changedKey.size() > MODIFY_TIME_SUFFIX.length() && changedKey.substr(dotPos) == MODIFY_TIME_SUFFIX) || + (changedKey.size() > SIZE_SUFFIX.length() && changedKey.substr(dotPos) == SIZE_SUFFIX)) { + assetKey = changedKey.substr(0, dotPos); + return true; + } + return false; +} + +void WatcherProxy::SetAssetChangeCallBack(const AssetChangeCallback &assetChangeCallback) { - objectWatcher_->OnChanged(sessionid, changedData); + assetChangeCallback_ = assetChangeCallback; } DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &bundleName) diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp index 96b87453..cf78cb81 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -22,6 +22,8 @@ #include "object_service_proxy.h" #include "objectstore_errors.h" #include "softbus_adapter.h" +#include "string_utils.h" +#include "bytes_utils.h" namespace OHOS::ObjectStore { FlatObjectStore::FlatObjectStore(const std::string &bundleName) @@ -107,6 +109,7 @@ uint32_t FlatObjectStore::Delete(const std::string &sessionId) return status; } cacheManager_->UnregisterDataChange(bundleName_, sessionId); + cacheManager_->DeleteSnapshot(bundleName_, sessionId); return SUCCESS; } @@ -145,7 +148,7 @@ uint32_t FlatObjectStore::Put(const std::string &sessionId, const std::string &k return storageEngine_->UpdateItem(sessionId, key, value); } -uint32_t FlatObjectStore::Get(std::string &sessionId, const std::string &key, Bytes &value) +uint32_t FlatObjectStore::Get(const std::string &sessionId, const std::string &key, Bytes &value) { if (!storageEngine_->isOpened_ && storageEngine_->Open(bundleName_) != SUCCESS) { LOG_ERROR("FlatObjectStore::DB has not inited"); @@ -202,6 +205,23 @@ uint32_t FlatObjectStore::RevokeSave(const std::string &sessionId) return cacheManager_->RevokeSave(bundleName_, sessionId); } +uint32_t FlatObjectStore::BindAssetStore(const std::string &sessionId, AssetBindInfo &bindInfo, Asset &assetValue) +{ + std::unique_lock lck(mutex_); + sptr proxy = ClientAdaptor::GetObjectService(); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr."); + return ERR_PROCESSING; + } + int32_t status = proxy->BindAssetStore(bundleName_, sessionId, assetValue, bindInfo); + if (status != SUCCESS) { + LOG_ERROR("object bind asset failed code=%{public}d.", static_cast(status)); + } + LOG_DEBUG("object bind asset successful sessionId: %{public}s and assetName %{public}s", sessionId.c_str(), + assetValue.name.c_str()); + return status; +} + void FlatObjectStore::CheckRetrieveCache(const std::string &sessionId) { std::lock_guard lck(mutex_); @@ -222,6 +242,129 @@ void FlatObjectStore::FilterData(const std::string &sessionId, } } +uint32_t FlatObjectStore::PutDouble(const std::string &sessionId, const std::string &key, double value) +{ + Bytes data; + Type type = Type::TYPE_DOUBLE; + BytesUtils::PutNum(&type, 0, sizeof(type), data); + BytesUtils::PutNum(&value, sizeof(type), sizeof(value), data); + return Put(sessionId, FIELDS_PREFIX + key, data); +} + +uint32_t FlatObjectStore::PutBoolean(const std::string &sessionId, const std::string &key, bool value) +{ + Bytes data; + Type type = Type::TYPE_BOOLEAN; + BytesUtils::PutNum(&type, 0, sizeof(type), data); + BytesUtils::PutNum(&value, sizeof(type), sizeof(value), data); + return Put(sessionId, FIELDS_PREFIX + key, data); +} + +uint32_t FlatObjectStore::PutString(const std::string &sessionId, const std::string &key, const std::string &value) +{ + Bytes data; + Type type = Type::TYPE_STRING; + BytesUtils::PutNum(&type, 0, sizeof(type), data); + Bytes dst = StringUtils::StrToBytes(value); + data.insert(data.end(), dst.begin(), dst.end()); + return Put(sessionId, FIELDS_PREFIX + key, data); +} + +uint32_t FlatObjectStore::GetDouble(const std::string &sessionId, const std::string &key, double &value) +{ + Bytes data; + Bytes keyBytes = StringUtils::StrToBytes(key); + uint32_t status = Get(sessionId, FIELDS_PREFIX + key, data); + if (status != SUCCESS) { + LOG_ERROR("GetDouble field not exist. %{public}d %{public}s", status, key.c_str()); + return status; + } + status = BytesUtils::GetNum(data, sizeof(Type), &value, sizeof(value)); + if (status != SUCCESS) { + LOG_ERROR("GetDouble getNum err. %{public}d", status); + } + return status; +} + +uint32_t FlatObjectStore::GetBoolean(const std::string &sessionId, const std::string &key, bool &value) +{ + Bytes data; + Bytes keyBytes = StringUtils::StrToBytes(key); + uint32_t status = Get(sessionId, FIELDS_PREFIX + key, data); + if (status != SUCCESS) { + LOG_ERROR("GetBoolean field not exist. %{public}d %{public}s", status, key.c_str()); + return status; + } + status = BytesUtils::GetNum(data, sizeof(Type), &value, sizeof(value)); + if (status != SUCCESS) { + LOG_ERROR("GetBoolean getNum err. %{public}d", status); + return status; + } + return SUCCESS; +} + +uint32_t FlatObjectStore::GetString(const std::string &sessionId, const std::string &key, std::string &value) +{ + Bytes data; + uint32_t status = Get(sessionId, FIELDS_PREFIX + key, data); + if (status != SUCCESS) { + LOG_ERROR("GetString field not exist. %{public}d %{public}s", status, key.c_str()); + return status; + } + status = StringUtils::BytesToStrWithType(data, value); + if (status != SUCCESS) { + LOG_ERROR("GetString dataToVal err. %{public}d", status); + } + return status; +} + +uint32_t FlatObjectStore::PutComplex(const std::string &sessionId, const std::string &key, + const std::vector &value) +{ + Bytes data; + Type type = Type::TYPE_COMPLEX; + BytesUtils::PutNum(&type, 0, sizeof(type), data); + data.insert(data.end(), value.begin(), value.end()); + uint32_t status = Put(sessionId, FIELDS_PREFIX + key, data); + if (status != SUCCESS) { + LOG_ERROR("PutBoolean setField err %{public}d", status); + } + return status; +} + +uint32_t FlatObjectStore::GetComplex(const std::string &sessionId, const std::string &key, + std::vector &value) +{ + uint32_t status = Get(sessionId, FIELDS_PREFIX + key, value); + if (status != SUCCESS) { + LOG_ERROR("GetString field not exist. %{public}d %{public}s", status, key.c_str()); + return status; + } + value.erase(value.begin(), value.begin() + sizeof(Type)); + return status; +} + +uint32_t FlatObjectStore::GetType(const std::string &sessionId, const std::string &key, Type &type) +{ + Bytes data; + uint32_t status = Get(sessionId, FIELDS_PREFIX + key, data); + if (status != SUCCESS) { + LOG_ERROR("GetString field not exist. %{public}d %{public}s", status, key.c_str()); + return status; + } + status = BytesUtils::GetNum(data, 0, &type, sizeof(type)); + if (status != SUCCESS) { + LOG_ERROR("GetBoolean getNum err. %{public}d", status); + return status; + } + return SUCCESS; +} + +std::string FlatObjectStore::GetBundleName() +{ + return bundleName_; +} + CacheManager::CacheManager() { } @@ -374,4 +517,19 @@ int32_t CacheManager::UnregisterDataChange(const std::string &bundleName, const LOG_INFO("object unregister data change observer successful"); return status; } + +int32_t CacheManager::DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) +{ + sptr proxy = ClientAdaptor::GetObjectService(); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr."); + return ERR_NULL_PTR; + } + int32_t status = proxy->DeleteSnapshot(bundleName, sessionId); + if (status != SUCCESS) { + LOG_ERROR("object delete snapshot failed code=%d.", static_cast(status)); + } + LOG_INFO("object delete snapshot successful"); + return status; +} } // namespace OHOS::ObjectStore diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/dev_manager.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/dev_manager.cpp index ff58820a..2e480ebf 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/dev_manager.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/dev_manager.cpp @@ -26,6 +26,7 @@ namespace OHOS { namespace ObjectStore { using namespace OHOS::DistributedHardware; +using DevInfo = OHOS::DistributedHardware::DmDeviceInfo; constexpr int32_t DM_OK = 0; constexpr int32_t DM_ERROR = -1; constexpr const char *PKG_NAME = "ohos.objectstore"; @@ -148,5 +149,27 @@ std::string DevManager::GetUuidByNodeId(const std::string &nodeId) const return uuid; } +const DevManager::DetailInfo &DevManager::GetLocalDevice() +{ + std::lock_guard lockGuard(mutex_); + if (!localInfo_.uuid.empty()) { + return localInfo_; + } + DevInfo info; + auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info); + if (ret != DM_OK) { + LOG_ERROR("get local device info fail"); + return invalidDetail_; + } + auto networkId = std::string(info.networkId); + std::string uuid; + DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid); + if (uuid.empty() || networkId.empty()) { + return invalidDetail_; + } + localInfo_.networkId = std::move(networkId); + localInfo_.uuid = std::move(uuid); + return localInfo_; +} } // namespace ObjectStore } // namespace OHOS \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp index 9b57404d..eedef6e9 100644 --- a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp +++ b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp @@ -17,9 +17,9 @@ #include "object_service_proxy.h" #include -#include "itypes_util.h" #include "log_print.h" #include "objectstore_errors.h" +#include "object_types_util.h" namespace OHOS::DistributedObject { using namespace ObjectStore; @@ -59,6 +59,38 @@ int32_t ObjectServiceProxy::ObjectStoreSave(const std::string &bundleName, const return reply.ReadInt32(); } +int32_t ObjectServiceProxy::OnAssetChanged(const std::string &bundleName, const std::string &sessionId, + const std::string &deviceId, const Asset &assetValue) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(ObjectServiceProxy::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return ERR_IPC; + } + if (!ITypesUtil::Marshal(data, bundleName, sessionId, deviceId)) { + ZLOGE("Marshalling failed, bundleName = %{public}s", bundleName.c_str()); + return ERR_IPC; + } + if (!ITypesUtil::Marshalling(assetValue, data)) { + ZLOGE("Marshalling failed assetValue"); + return ERR_IPC; + } + MessageParcel reply; + MessageOption mo { MessageOption::TF_SYNC }; + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("OnAssetChanged remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = remoteObject->SendRequest( + static_cast(ObjectCode::OBJECTSTORE_ON_ASSET_CHANGED), data, reply, mo); + if (error != 0) { + ZLOGE("SendRequest returned %d", error); + return ERR_IPC; + } + return reply.ReadInt32(); +} + int32_t ObjectServiceProxy::ObjectStoreRevokeSave( const std::string &bundleName, const std::string &sessionId, sptr callback) { @@ -177,4 +209,63 @@ int32_t ObjectServiceProxy::UnregisterDataChangeObserver(const std::string &bund } return reply.ReadInt32(); } + +int32_t ObjectServiceProxy::BindAssetStore(const std::string &bundleName, const std::string &sessionId, + Asset &asset, AssetBindInfo &bindInfo) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(ObjectServiceProxy::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return ERR_IPC; + } + + if (!ITypesUtil::Marshal(data, bundleName, sessionId, asset, bindInfo)) { + ZLOGE("Marshalling failed, bundleName = %{public}s", bundleName.c_str()); + return ERR_IPC; + } + + MessageParcel reply; + MessageOption mo { MessageOption::TF_SYNC }; + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("BindAssetStore remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_BIND_ASSET_STORE), data, reply, mo); + if (error != 0) { + ZLOGE("SendRequest returned %d", error); + return ERR_IPC; + } + return reply.ReadInt32(); +} + +int32_t ObjectServiceProxy::DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(ObjectServiceProxy::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return ERR_IPC; + } + + if (!ITypesUtil::Marshal(data, bundleName, sessionId)) { + ZLOGE("Marshalling failed, bundleName = %{public}s", bundleName.c_str()); + return ERR_IPC; + } + + MessageParcel reply; + MessageOption mo { MessageOption::TF_SYNC }; + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("DeleteSnapshot remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_DELETE_SNAPSHOT), data, reply, mo); + if (error != 0) { + ZLOGE("SendRequest returned %d", error); + return ERR_IPC; + } + return reply.ReadInt32(); +} } // namespace OHOS::DistributedObject diff --git a/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn index 21bff7cd..890bb211 100644 --- a/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn @@ -14,12 +14,14 @@ #####################hydra-fuzz################### import("//build/config/features.gni") import("//build/test.gni") +import("//foundation/distributeddatamgr/data_object/data_object.gni") config("module_private_config") { visibility = [ ":*" ] include_dirs = [ "../../../../../frameworks/innerkitsimpl/include/adaptor", "../../../../../frameworks/innerkitsimpl/include/common", + "${data_object_base_path}/frameworks/innerkitsimpl/include", ] } @@ -37,7 +39,10 @@ ohos_fuzztest("ObjectStoreFuzzTest") { "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", ] - external_deps = [ "hilog:libhilog" ] + external_deps = [ + "hilog:libhilog", + "relational_store:common_type", + ] } ############################################################################### diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn index af7d02e5..53392240 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn @@ -30,6 +30,7 @@ config("module_private_config") { "${data_object_innerkits_path}/include/adaptor", "${data_object_innerkits_path}/include/common", "${data_object_innerkits_path}/include/communicator", + "${data_object_innerkits_path}/include", "${kv_store_include_path}/include", "${kv_store_include_path}/interfaces/include/", "${kv_store_include_path}/interfaces/include/relational", @@ -55,6 +56,7 @@ ohos_unittest("NativeObjectStoreTest") { "access_token:libnativetoken", "access_token:libtoken_setproc", "hilog:libhilog", + "relational_store:common_type", ] deps = [ diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp index 8bc1f644..648e1448 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp @@ -977,32 +977,6 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_GetTable_004, TestSize.Level1) delete objectStorageEngine; } -/** - * @tc.name: FlatObjectStore_FilterData_001 - * @tc.desc: test FlatObjectStore FilterData. - * @tc.type: FUNC - */ -HWTEST_F(NativeObjectStoreTest, DistributedObject_FilterData_001, TestSize.Level1) -{ - std::string bundleName = "default05"; - std::string sessionId = "session05"; - std::vector value = { 1, 8 }; - FlatObjectStore *flatObjectStore = new FlatObjectStore(bundleName); - uint32_t ret = flatObjectStore->CreateObject(sessionId); - EXPECT_EQ(SUCCESS, ret); - ret = flatObjectStore->Put(sessionId, "phone", value); - EXPECT_EQ(SUCCESS, ret); - ret = flatObjectStore->Put(sessionId, "age", value); - EXPECT_EQ(SUCCESS, ret); - std::map> data = { { "age", value }, { "age", value } }; - auto dataSize = data.size(); - flatObjectStore->FilterData(sessionId, data); - EXPECT_GT(dataSize, data.size()); - ret = flatObjectStore->Delete(sessionId); - EXPECT_EQ(SUCCESS, ret); - delete flatObjectStore; -} - /** * @tc.name: FlatObjectStore_UpdateItems_001 * @tc.desc: test ObjectStorageEngine UpdateItems. input data is empty. diff --git a/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobject.h b/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobject.h index 9cca0f54..91fd9f9e 100644 --- a/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobject.h +++ b/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobject.h @@ -33,6 +33,7 @@ public: static napi_value JSPut(napi_env env, napi_callback_info info); static napi_value JSSave(napi_env env, napi_callback_info info); static napi_value JSRevokeSave(napi_env env, napi_callback_info info); + static napi_value JSBindAssetStore(napi_env env, napi_callback_info info); static napi_value GetCons(napi_env env); private: diff --git a/data_object/frameworks/jskitsimpl/include/common/js_util.h b/data_object/frameworks/jskitsimpl/include/common/js_util.h index ad7e559e..a2bff54b 100644 --- a/data_object/frameworks/jskitsimpl/include/common/js_util.h +++ b/data_object/frameworks/jskitsimpl/include/common/js_util.h @@ -22,6 +22,7 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" +#include "object_types.h" namespace OHOS::ObjectStore { class JSUtil final { @@ -37,6 +38,17 @@ public: /* napi_value <-> std::string */ static napi_status GetValue(napi_env env, napi_value in, std::string &out); static napi_status SetValue(napi_env env, const std::string &in, napi_value &out); + + /* napi_value <-> int32_t */ + static napi_status GetValue(napi_env env, napi_value in, int32_t& out); + static napi_status SetValue(napi_env env, const int32_t& in, napi_value& out); + + static napi_status GetValue(napi_env env, napi_value in, uint32_t& out); + static napi_status SetValue(napi_env env, const uint32_t& in, napi_value& out); + + /* napi_value <-> int64_t */ + static napi_status GetValue(napi_env env, napi_value in, int64_t& out); + static napi_status SetValue(napi_env env, const int64_t& in, napi_value& out); /* napi_value <-> std::vector */ static napi_status GetValue(napi_env env, napi_value in, std::vector &out); @@ -46,7 +58,76 @@ public: static napi_status GetValue(napi_env env, napi_value in, std::vector &out); static napi_status SetValue(napi_env env, const std::vector &in, napi_value &out); + static napi_status GetValue(napi_env env, napi_value in, Assets &assets); + + static napi_status GetValue(napi_env env, napi_value in, Asset &asset); + + static napi_status GetValue(napi_env env, napi_value in, AssetBindInfo &out); + + static napi_status GetValue(napi_env env, napi_value in, ValuesBucket &out); + + static napi_status GetValue(napi_env env, napi_value jsValue, std::monostate &out); + static void GenerateNapiError(napi_env env, int32_t status, int32_t &errCode, std::string &errMessage); + + static bool IsNull(napi_env env, napi_value value); + + template + static inline napi_status GetNamedProperty(napi_env env, napi_value in, const std::string& prop, + T& value, bool optional = false) + { + bool hasProp = false; + napi_status status = napi_has_named_property(env, in, prop.c_str(), &hasProp); + if (!hasProp) { + status = optional ? napi_ok : napi_generic_failure; + return status; + } + + if ((status == napi_ok) && hasProp) { + napi_value inner = nullptr; + status = napi_get_named_property(env, in, prop.c_str(), &inner); + if (!optional && IsNull(env, inner)) { + return napi_generic_failure; + } + if ((status == napi_ok) && (inner != nullptr)) { + return GetValue(env, inner, value); + } + } + return napi_invalid_arg; + }; + + template + static napi_status GetValues(napi_env env, napi_value jsValue, T &value) + { + return napi_invalid_arg; + } + + template + static napi_status GetValues(napi_env env, napi_value jsValue, T &value) + { + First cValue; + auto ret = GetValue(env, jsValue, cValue); + if (ret == napi_ok) { + value = cValue; + return ret; + } + return GetValues(env, jsValue, value); + } + + template + static napi_status GetValue(napi_env env, napi_value jsValue, std::variant &value) + { + napi_valuetype type; + napi_status status = napi_typeof(env, jsValue, &type); + if (status != napi_ok) { + return napi_invalid_arg; + } + if (type == napi_undefined) { + return napi_generic_failure; + } + + return GetValues(env, jsValue, value); + }; }; #define NAPI_ASSERT_ERRCODE_V9(env, assertion, version, err) \ diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp index 110bdf1c..a603ac31 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp @@ -113,6 +113,7 @@ napi_value JSDistributedObject::GetCons(napi_env env) DECLARE_NAPI_FUNCTION("get", JSDistributedObject::JSGet), DECLARE_NAPI_FUNCTION("save", JSDistributedObject::JSSave), DECLARE_NAPI_FUNCTION("revokeSave", JSDistributedObject::JSRevokeSave), + DECLARE_NAPI_FUNCTION("bindAssetStore", JSDistributedObject::JSBindAssetStore), }; napi_status status = napi_define_class(env, distributedObjectName, strlen(distributedObjectName), @@ -348,4 +349,40 @@ napi_value JSDistributedObject::GetRevokeSaveResultCons(napi_env env, std::strin NOT_MATCH_RETURN_NULL(status == napi_ok); return result; } + +napi_value JSDistributedObject::JSBindAssetStore(napi_env env, napi_callback_info info) +{ + struct BindAssetStoreContext : public ContextBase { + std::string assetKey; + AssetBindInfo bindInfo; + JSObjectWrapper *wrapper; + }; + auto ctxt = std::make_shared(); + auto input = [env, ctxt](size_t argc, napi_value *argv) { + INVALID_ARGS_RETURN_ERROR(ctxt, argc >= 2, "arguments error", std::make_shared("2")); + ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->assetKey); + INVALID_ARGS_RETURN_ERROR(ctxt, ctxt->status == napi_ok, "arguments error", + std::make_shared("assetKey", "string")); + + ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->bindInfo); + INVALID_ARGS_RETURN_ERROR(ctxt, ctxt->status == napi_ok, "arguments error", + std::make_shared("bindInfo", "BindInfo")); + JSObjectWrapper *wrapper = nullptr; + napi_status status = napi_unwrap(env, ctxt->self, (void **)&wrapper); + NOT_MATCH_RETURN_VOID(status == napi_ok && wrapper != nullptr && wrapper->GetObject() != nullptr); + ctxt->wrapper = wrapper; + }; + ctxt->GetCbInfo(env, info, input); + NAPI_ASSERT_ERRCODE(env, ctxt->status == napi_ok, ctxt->error); + auto execute = [ctxt]() { + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper != nullptr, ctxt, "wrapper is null"); + CHECH_STATUS_RETURN_VOID(env, ctxt->wrapper->GetObject() != nullptr, ctxt, "object is null"); + uint32_t status = ctxt->wrapper->GetObject()->BindAssetStore(ctxt->assetKey, ctxt->bindInfo); + LOG_INFO("BindAssetStore return: %{public}d", status); + INVALID_API_THROW_ERROR(status != ERR_PROCESSING); + INVALID_STATUS_THROW_ERROR(status == SUCCESS, "operation failed"); + ctxt->status = napi_ok; + }; + return NapiQueue::AsyncWork(env, ctxt, std::string(__FUNCTION__), execute); +} } // namespace OHOS::ObjectStore \ No newline at end of file diff --git a/data_object/frameworks/jskitsimpl/src/common/js_util.cpp b/data_object/frameworks/jskitsimpl/src/common/js_util.cpp index d12446b0..ec058419 100644 --- a/data_object/frameworks/jskitsimpl/src/common/js_util.cpp +++ b/data_object/frameworks/jskitsimpl/src/common/js_util.cpp @@ -18,6 +18,7 @@ #include #include "logger.h" +#include "common_value_object.h" namespace OHOS::ObjectStore { constexpr int32_t STR_MAX_LENGTH = 4096; @@ -49,6 +50,28 @@ napi_status JSUtil::SetValue(napi_env env, const double &in, napi_value &out) return napi_create_double(env, in, &out); } +/* napi_value <-> int64_t */ +napi_status JSUtil::GetValue(napi_env env, napi_value in, int64_t& out) +{ + return napi_get_value_int64(env, in, &out); +} + +napi_status JSUtil::SetValue(napi_env env, const int64_t& in, napi_value& out) +{ + return napi_create_int64(env, in, &out); +} + +/* napi_value <-> uint32_t */ +napi_status JSUtil::GetValue(napi_env env, napi_value in, uint32_t& out) +{ + return napi_get_value_uint32(env, in, &out); +} + +napi_status JSUtil::SetValue(napi_env env, const uint32_t& in, napi_value& out) +{ + return napi_create_uint32(env, in, &out); +} + /* napi_value <-> std::string */ napi_status JSUtil::GetValue(napi_env env, napi_value in, std::string &out) { @@ -152,4 +175,119 @@ napi_status JSUtil::SetValue(napi_env env, const std::vector &in, napi_ LOG_ERROR_RETURN((status == napi_ok), "napi_value <- std::vector invalid value", status); return status; } + +napi_status JSUtil::GetValue(napi_env env, napi_value in, AssetBindInfo &bindInfo) +{ + napi_status status = napi_invalid_arg; + status = GetNamedProperty(env, in, "storeName", bindInfo.storeName); + LOG_ERROR_RETURN(status == napi_ok, "get store param failed", status); + status = GetNamedProperty(env, in, "tableName", bindInfo.tableName); + LOG_ERROR_RETURN(status == napi_ok, "get table param failed", status); + status = GetNamedProperty(env, in, "primaryKey", bindInfo.primaryKey); + + LOG_ERROR_RETURN(status == napi_ok, "get primary param failed", status); + status = GetNamedProperty(env, in, "field", bindInfo.field); + LOG_ERROR_RETURN(status == napi_ok, "get field param failed", status); + status = GetNamedProperty(env, in, "assetName", bindInfo.assetName); + LOG_ERROR_RETURN(status == napi_ok, "get assetName param failed", status); + return status; +} + +napi_status JSUtil::GetValue(napi_env env, napi_value in, Asset &asset) +{ + napi_valuetype type; + napi_status status = napi_typeof(env, in, &type); + LOG_ERROR_RETURN((status == napi_ok) && (type == napi_object), "Asset type invalid", napi_invalid_arg); + status = GetNamedProperty(env, in, "name", asset.name); + LOG_ERROR_RETURN(status == napi_ok, "get name param failed", status); + status = GetNamedProperty(env, in, "uri", asset.uri); + LOG_ERROR_RETURN(status == napi_ok, "get uri param failed", status); + status = GetNamedProperty(env, in, "path", asset.path); + LOG_ERROR_RETURN(status == napi_ok, "get path param failed", status); + status = GetNamedProperty(env, in, "createTime", asset.createTime); + LOG_ERROR_RETURN(status == napi_ok, "get createTime param failed", status); + status = GetNamedProperty(env, in, "modifyTime", asset.modifyTime); + LOG_ERROR_RETURN(status == napi_ok, "get modifyTime param failed", status); + status = GetNamedProperty(env, in, "size", asset.size); + LOG_ERROR_RETURN(status == napi_ok, "get size param failed", status); + status = GetNamedProperty(env, in, "status", asset.status, true); + LOG_ERROR_RETURN(status == napi_ok, "get status param failed", status); + return status; +} + +napi_status JSUtil::GetValue(napi_env env, napi_value in, Assets &assets) +{ + assets.clear(); + bool isArray = false; + napi_is_array(env, in, &isArray); + LOG_ERROR_RETURN(isArray, "not an array", napi_generic_failure); + + uint32_t arrLen = 0; + napi_status status = napi_get_array_length(env, in, &arrLen); + LOG_ERROR_RETURN((status == napi_ok) && (arrLen > 0), "get_array failed!", status); + for (uint32_t i = 0; i < arrLen; ++i) { + napi_value item = nullptr; + status = napi_get_element(env, in, i, &item); + LOG_ERROR_RETURN((item != nullptr) && (status == napi_ok), "no element", status); + Asset asset; + status = GetValue(env, item, asset); + LOG_ERROR_RETURN(status == napi_ok, "not a asset object", status); + assets.push_back(asset); + } + return status; +} + +napi_status JSUtil::GetValue(napi_env env, napi_value in, ValuesBucket &out) +{ + napi_value keys = 0; + napi_get_all_property_names(env, in, napi_key_own_only, + static_cast(napi_key_enumerable | napi_key_skip_symbols), + napi_key_numbers_to_strings, &keys); + uint32_t arrLen = 0; + auto status = napi_get_array_length(env, keys, &arrLen); + LOG_ERROR_RETURN(status == napi_ok, "error! The type of values must be a ValuesBucket.", status); + for (size_t i = 0; i < arrLen; ++i) { + napi_value jsKey = 0; + status = napi_get_element(env, keys, i, &jsKey); + LOG_ERROR_RETURN((status == napi_ok), "no element! The type of values must be a ValuesBucket.", status); + std::string key; + status = GetValue(env, jsKey, key); + LOG_ERROR_RETURN((status == napi_ok), "get key failed", status); + napi_value valueJs = 0; + napi_get_property(env, in, jsKey, &valueJs); + ValueObject valueObject; + status = GetValue(env, valueJs, valueObject.value); + if (status == napi_ok) { + out.Put(key, valueObject); + } else if (status != napi_generic_failure) { + LOG_ERROR("The value type %{public}s is invalid: ", key.c_str()); + return status; + } + } + return napi_ok; +} + +napi_status JSUtil::GetValue(napi_env env, napi_value jsValue, std::monostate &out) +{ + napi_value tempValue; + napi_get_null(env, &tempValue); + bool equal = false; + napi_strict_equals(env, jsValue, tempValue, &equal); + if (equal) { + out = std::monostate(); + return napi_ok; + } + LOG_DEBUG("jsValue is not null"); + return napi_invalid_arg; +} + +bool JSUtil::IsNull(napi_env env, napi_value value) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, value, &type); + if (status == napi_ok && (type == napi_undefined || type == napi_null)) { + return true; + } + return false; +} } // namespace OHOS::ObjectStore diff --git a/data_object/interfaces/innerkits/BUILD.gn b/data_object/interfaces/innerkits/BUILD.gn index de251224..a2db94aa 100644 --- a/data_object/interfaces/innerkits/BUILD.gn +++ b/data_object/interfaces/innerkits/BUILD.gn @@ -41,6 +41,7 @@ object_source_config = [ "../../frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp", "../../frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp", "../../frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp", + "../../frameworks/innerkitsimpl/src/adaptor/asset_change_timer.cpp", "../../frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp", "../../frameworks/innerkitsimpl/src/communicator/app_device_handler.cpp", "../../frameworks/innerkitsimpl/src/communicator/app_pipe_handler.cpp", @@ -53,6 +54,7 @@ object_source_config = [ "../../frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp", "../../frameworks/innerkitsimpl/src/object_callback_stub.cpp", "../../frameworks/innerkitsimpl/src/object_service_proxy.cpp", + "../../frameworks/innerkitsimpl/src/object_types_util.cpp", ] object_deps_config = [ "//third_party/bounds_checking_function:libsec_shared", @@ -69,6 +71,7 @@ object_external_deps_config = [ "kv_store:distributeddata_inner", "kv_store:distributeddb", "samgr:samgr_proxy", + "relational_store:common_type", ] ohos_shared_library("distributeddataobject_impl") { branch_protector_ret = "pac_ret" diff --git a/data_object/interfaces/innerkits/distributed_object.h b/data_object/interfaces/innerkits/distributed_object.h index 3270dec6..71a931f0 100644 --- a/data_object/interfaces/innerkits/distributed_object.h +++ b/data_object/interfaces/innerkits/distributed_object.h @@ -19,6 +19,7 @@ #include #include #include +#include "object_types.h" namespace OHOS::ObjectStore { enum Type : uint8_t { @@ -151,6 +152,16 @@ public: * @return Returns sessionId of the object. */ virtual std::string &GetSessionId() = 0; + + /** + * @brief Bind Asset. + * + * @param assetKey Indicates the assetKey key. + * @param bindInfo Indicates asset info. + * + * @return Returns 0 for success, others for failure. + */ + virtual uint32_t BindAssetStore(const std::string &assetKey, AssetBindInfo &bindInfo) = 0; }; class ObjectWatcher { diff --git a/data_object/interfaces/jskits/BUILD.gn b/data_object/interfaces/jskits/BUILD.gn index 4c8a6890..8023e95b 100644 --- a/data_object/interfaces/jskits/BUILD.gn +++ b/data_object/interfaces/jskits/BUILD.gn @@ -40,6 +40,7 @@ config("objectstore_config") { "../../frameworks/jskitsimpl/include/common", "../../frameworks/innerkitsimpl/include/adaptor", "../../frameworks/innerkitsimpl/include/common", + "../../frameworks/innerkitsimpl/include", "../../frameworks/innerkitsimpl/include/communicator", "../../interfaces/innerkits", "${kvstore_path}/common", @@ -112,6 +113,7 @@ ohos_shared_library("distributeddataobject") { "hilog:libhilog", "kv_store:distributeddb", "napi:ace_napi", + "relational_store:common_type", ] public_configs = [ ":objectstore_public_config" ] diff --git a/data_object/interfaces/jskits/distributed_data_object.js b/data_object/interfaces/jskits/distributed_data_object.js index 0d24323b..fd3493f9 100644 --- a/data_object/interfaces/jskits/distributed_data_object.js +++ b/data_object/interfaces/jskits/distributed_data_object.js @@ -12,13 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + const distributedObject = requireInternal('data.distributedDataObject'); const SESSION_ID = '__sessionId'; const VERSION = '__version'; const COMPLEX_TYPE = '[COMPLEX]'; const STRING_TYPE = '[STRING]'; const NULL_TYPE = '[NULL]'; +const ASSET_KEYS = ['status', 'name', 'uri', 'path', 'createTime', 'modifyTime', 'size']; +const STATUS_INDEX = 0; +const ASSET_KEY_SEPARATOR = '.'; const JS_ERROR = 1; const SDK_VERSION_8 = 8; const SDK_VERSION_9 = 9; @@ -163,6 +166,53 @@ function setObjectValue(object, key, newValue) { } } +function isAsset(obj) { + if (Object.prototype.toString.call(obj) !== '[object Object]') { + return false; + } + let length = obj.hasOwnProperty(ASSET_KEYS[STATUS_INDEX]) ? ASSET_KEYS.length : ASSET_KEYS.length - 1; + if (Object.keys(obj).length !== length) { + return false; + } + if (obj.hasOwnProperty(ASSET_KEYS[STATUS_INDEX]) && typeof obj[ASSET_KEYS[STATUS_INDEX]] !== 'number') { + return false; + } + for (const key of ASSET_KEYS.slice(1)) { + if (!obj.hasOwnProperty(key) || typeof obj[key] !== 'string') { + return false; + } + } + return true; +} + +function getAssetValue(object, key, obj) { + Object.keys(obj).forEach(subKey => { + Object.defineProperty(obj, subKey, { + enumerable: true, + configurable: true, + get: function () { + return getObjectValue(object, key + ASSET_KEY_SEPARATOR + subKey); + }, + set: function (newValue) { + setObjectValue(object, key + ASSET_KEY_SEPARATOR + subKey, newValue); + } + }); + }); + return obj; +} + +function setAssetValue(object, key, newValue) { + if (!isAsset(newValue)) { + throw { + code: 401, + message: 'cannot set ' + key + ' by non Asset type data' + }; + } + Object.values(ASSET_KEYS).forEach(subKey => { + setObjectValue(object, key + ASSET_KEY_SEPARATOR + subKey, newValue[subKey]); + }); +} + function joinSession(version, obj, objectId, sessionId, context) { console.info('start joinSession ' + sessionId); if (obj == null || sessionId == null || sessionId === '') { @@ -183,16 +233,29 @@ function joinSession(version, obj, objectId, sessionId, context) { } Object.keys(obj).forEach(key => { console.info('start define ' + key); - Object.defineProperty(object, key, { - enumerable: true, - configurable: true, - get: function () { - return getObjectValue(object, key); - }, - set: function (newValue) { - setObjectValue(object, key, newValue); - } - }); + if (isAsset(obj[key])) { + Object.defineProperty(object, key, { + enumerable: true, + configurable: true, + get: function () { + return getAssetValue(object, key, obj[key]); + }, + set: function (newValue) { + setAssetValue(object, key, newValue); + } + }); + } else { + Object.defineProperty(object, key, { + enumerable: true, + configurable: true, + get: function () { + return getObjectValue(object, key); + }, + set: function (newValue) { + setObjectValue(object, key, newValue); + } + }); + } if (obj[key] !== undefined) { object[key] = obj[key]; } @@ -218,6 +281,16 @@ function leaveSession(version, obj) { writable: true, enumerable: true, }); + if (isAsset(obj[key])) { + Object.keys(obj[key]).forEach(subKey => { + Object.defineProperty(obj[key], subKey, { + value: obj[key][subKey], + configurable: true, + writable: true, + enumerable: true, + }); + }); + } }); // disconnect,delete object distributedObject.destroyObjectSync(version, obj); @@ -251,7 +324,7 @@ function newDistributedV9(context, obj) { }; if (typeof context !== 'object') { checkparameter('context', 'Context'); - } + } if (typeof obj !== 'object') { checkparameter('source', 'object'); } @@ -336,6 +409,14 @@ class DistributedV9 { return this.__proxy.revokeSave(callback); } + bindAssetStore(assetkey, bindInfo, callback) { + if (this.__proxy[SESSION_ID] == null || this.__proxy[SESSION_ID] === '') { + console.info('not join a session, can not do bindAssetStore'); + return JS_ERROR; + } + return this.__proxy.bindAssetStore(assetkey, bindInfo, callback); + } + __context; __proxy; __objectId; diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index 086597c2..4f52352f 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -62,6 +62,7 @@ "data_share", "device_auth", "device_manager", + "dfs_service", "dsoftbus", "hilog", "hisysevent", @@ -129,6 +130,9 @@ "metadata/strategy_meta_data.h", "metadata/user_meta_data.h", "serializable/serializable.h", + "snapshot/bind_event.h", + "snapshot/machine_status.h", + "snapshot/snapshot.h", "store/auto_cache.h", "store/cursor.h", "store/general_store.h", diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_strategy.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_strategy.cpp index f4e72eba..ee1e2708 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_strategy.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #define LOG_TAG "CommunicationStrategy" #include "communication_strategy.h" #include "log_print.h" @@ -45,20 +45,21 @@ size_t CommunicationStrategy::CalcSyncDataSize(const std::string &deviceId) return dataSize; } -void CommunicationStrategy::SetStrategy(const std::string &deviceId, Strategy strategy, - const std::function &action) +void CommunicationStrategy::SetStrategy(const std::string &deviceId, Strategy strategy) { auto value = strategy; if (strategy == Strategy::ON_LINE_SELECT_CHANNEL && CalcSyncDataSize(deviceId) < SWITCH_CONNECTION_THRESHOLD) { value = Strategy::DEFAULT; } - if (action) { - action(deviceId, value); - } strategys_.InsertOrAssign(deviceId, value); return ; } +void CommunicationStrategy::RemoveStrategy(const std::string &deviceId) +{ + (void)strategys_.Erase(deviceId); +} + CommunicationStrategy::Strategy CommunicationStrategy::GetStrategy(const std::string &deviceId) { auto result = strategys_.Find(deviceId); diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index e143ff1d..237d380c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -98,7 +98,7 @@ private: int32_t NetConnCallbackObserver::NetAvailable(sptr &netHandle) { ZLOGI("OnNetworkAvailable"); - dmAdapter_.isNetAvailable_ = true; + dmAdapter_.SetNetAvailable(true); dmAdapter_.Online(dmAdapter_.cloudDmInfo); return DistributedKv::SUCCESS; } @@ -106,7 +106,7 @@ int32_t NetConnCallbackObserver::NetAvailable(sptr & int32_t NetConnCallbackObserver::NetLost(sptr &netHandle) { ZLOGI("OnNetLost"); - dmAdapter_.isNetAvailable_ = false; + dmAdapter_.SetNetAvailable(false); dmAdapter_.Offline(dmAdapter_.cloudDmInfo); return DistributedKv::SUCCESS; } @@ -578,6 +578,22 @@ bool DeviceManagerAdapter::RegOnNetworkChange() bool DeviceManagerAdapter::IsNetworkAvailable() { + { + std::shared_lock lock(mutex_); + if (isNetAvailable_ || expireTime_ > std::chrono::steady_clock::now()) { + return isNetAvailable_; + } + } + NetHandle handle; + auto status = NetConnClient::GetInstance().GetDefaultNet(handle); + return SetNetAvailable(status == 0 && handle.GetNetId() != 0); +} + +bool DeviceManagerAdapter::SetNetAvailable(bool isNetAvailable) +{ + std::unique_lock lock(mutex_); + isNetAvailable_ = isNetAvailable; + expireTime_ = std::chrono::steady_clock::now() + std::chrono::milliseconds(EFFECTIVE_DURATION); return isNetAvailable_; } } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index 4c41f5d9..640cb732 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -33,7 +33,7 @@ #include "softbus_client.h" namespace OHOS { namespace AppDistributedKv { -class SoftBusAdapter { +class SoftBusAdapter : public AppDistributedKv::AppDeviceChangeListener { public: SoftBusAdapter(); ~SoftBusAdapter(); @@ -71,12 +71,10 @@ public: uint32_t GetMtuSize(const DeviceId &deviceId); uint32_t GetTimeout(const DeviceId &deviceId); - std::shared_ptr GetConnect(const std::string &deviceId); - class SofBusDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceChangeListener { - void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, - const AppDistributedKv::DeviceChangeType &type) const override; - }; + void OnDeviceChanged(const AppDistributedKv::DeviceInfo& info, + const AppDistributedKv::DeviceChangeType& type) const override; + private: using Time = std::chrono::steady_clock::time_point; using Duration = std::chrono::steady_clock::duration; @@ -84,19 +82,17 @@ private: std::shared_ptr> GetSemaphore(int32_t connId); std::string DelConnect(int32_t connId); void DelSessionStatus(int32_t connId); - void AfterStrategyUpdate(const std::string &deviceId); Task GetCloseSessionTask(); static constexpr uint32_t WAIT_MAX_TIME = 19; static constexpr Time INVALID_NEXT = std::chrono::steady_clock::time_point::max(); static std::shared_ptr instance_; ConcurrentMap dataChangeListeners_{}; - ConcurrentMap> connects_{}; + ConcurrentMap>> connects_; bool flag_ = true; // only for br flag ISessionListener sessionListener_{}; std::mutex statusMutex_{}; std::map>> sessionsStatus_; std::function onBroadcast_; - static SofBusDeviceChangeListenerImpl listener_; std::mutex taskMutex_; ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; Time next_ = INVALID_NEXT; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index 6a0830fa..889c33a0 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -105,7 +105,6 @@ INodeStateCb g_callback = { .onNodeStatusChanged = OnCareEvent, }; } // namespace -SoftBusAdapter::SofBusDeviceChangeListenerImpl SoftBusAdapter::listener_; SoftBusAdapter::SoftBusAdapter() { ZLOGI("begin"); @@ -116,7 +115,7 @@ SoftBusAdapter::SoftBusAdapter() sessionListener_.OnBytesReceived = AppDataListenerWrap::OnBytesReceived; sessionListener_.OnMessageReceived = AppDataListenerWrap::OnBytesReceived; - auto status = DmAdapter::GetInstance().StartWatchDeviceChange(&listener_, {"softBusAdapter"}); + auto status = DmAdapter::GetInstance().StartWatchDeviceChange(this, {"softBusAdapter"}); if (status != Status::SUCCESS) { ZLOGW("register device change failed, status:%d", static_cast(status)); } @@ -166,28 +165,32 @@ Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppData } Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) + uint32_t length, const MessageInfo &info) { std::shared_ptr conn; connects_.Compute(deviceId.deviceId, - [this, &pipeInfo, &deviceId, &conn](const auto &key, std::shared_ptr &connect) -> bool { - if (connect != nullptr) { + [this, &pipeInfo, &deviceId, &conn, length](const auto& key, + std::vector> &connects) -> bool { + for (auto &connect : connects) { + if (connect->Support(length)) { + conn = connect; + return true; + } + } + auto connect = std::make_shared(pipeInfo, deviceId, [this](int32_t connId) { + return GetSessionStatus(connId); + }); + connects.emplace_back(connect); conn = connect; return true; - } - connect = std::make_shared(pipeInfo, deviceId, [this](int32_t connId) { - return GetSessionStatus(connId); }); - conn = connect; - return true; - }); if (conn == nullptr) { return Status::ERROR; } - auto status = conn->Send(dataInfo, totalLength); + auto status = conn->Send(dataInfo, length); if ((status != Status::NETWORK_ERROR) && (status != Status::RATE_LIMIT)) { Time now = std::chrono::steady_clock::now(); - auto expireTime = conn->GetExpireTime(); + auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now; lock_guard lock(taskMutex_); if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) { taskId_ = Context::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now); @@ -209,28 +212,36 @@ SoftBusAdapter::Task SoftBusAdapter::GetCloseSessionTask() return [this]() mutable { Time now = std::chrono::steady_clock::now(); std::vector> connToClose; - connects_.EraseIf([&now, &connToClose](const auto &key, const auto &conn) -> bool { - if (conn == nullptr) { - return true; - } - auto expireTime = conn->GetExpireTime(); - if (expireTime <= now) { - ZLOGD("[timeout] close session connId:%{public}d", conn->GetConnId()); - connToClose.emplace_back(conn); - return true; + connects_.ForEach([&now, &connToClose](const auto &key, auto &connects) -> bool { + std::vector> holdConnects; + for (auto conn : connects) { + if (conn == nullptr) { + continue; + } + auto expireTime = conn->GetExpireTime(); + if (expireTime <= now) { + ZLOGD("[timeout] close session connId:%{public}d", conn->GetConnId()); + connToClose.emplace_back(conn); + } else { + holdConnects.emplace_back(conn); + } } + connects = std::move(holdConnects); return false; }); + connects_.EraseIf([](const auto &key, const auto &conn) -> bool { return conn.empty(); }); Time next = INVALID_NEXT; lock_guard lg(taskMutex_); - connects_.ForEach([&next](const auto &key, const auto &conn) -> bool { - if (conn == nullptr) { - return false; - } - auto expireTime = conn->GetExpireTime(); - if (expireTime < next) { - next = expireTime; + connects_.ForEach([&next](const auto &key, auto &connects) -> bool { + for (auto conn : connects) { + if (conn == nullptr) { + continue; + } + auto expireTime = conn->GetExpireTime(); + if (expireTime < next) { + next = expireTime; + } } return false; }); @@ -244,38 +255,60 @@ SoftBusAdapter::Task SoftBusAdapter::GetCloseSessionTask() }; } -std::shared_ptr SoftBusAdapter::GetConnect(const std::string &deviceId) -{ - auto [status, vlaue] = connects_.Find(deviceId); - return vlaue; -} - uint32_t SoftBusAdapter::GetMtuSize(const DeviceId &deviceId) { - std::shared_ptr conn = GetConnect(deviceId.deviceId); - if (conn != nullptr) { - return conn->GetMtuSize(); - } - return DEFAULT_MTU_SIZE; + uint32_t mtuSize = DEFAULT_MTU_SIZE; + connects_.ComputeIfPresent(deviceId.deviceId, [&mtuSize](auto, auto &connects) { + uint32_t mtu = 0; + for (auto conn : connects) { + if (conn == nullptr) { + continue; + } + if (mtu < conn->GetMtuSize()) { + mtu = conn->GetMtuSize(); + } + } + if (mtu != 0) { + mtuSize = mtu; + } + return true; + }); + return mtuSize; } uint32_t SoftBusAdapter::GetTimeout(const DeviceId &deviceId) { - std::shared_ptr conn = GetConnect(deviceId.deviceId); - if (conn != nullptr) { - return conn->GetTimeout(); - } - return DEFAULT_TIMEOUT; + uint32_t interval = DEFAULT_TIMEOUT; + connects_.ComputeIfPresent(deviceId.deviceId, [&interval](auto, auto &connects) { + uint32_t time = 0; + for (auto conn : connects) { + if (conn == nullptr) { + continue; + } + if (time < conn->GetTimeout()) { + time = conn->GetTimeout(); + } + } + if (time != 0) { + interval = time; + } + return true; + }); + return interval; } std::string SoftBusAdapter::DelConnect(int32_t connId) { std::string name; - connects_.EraseIf([connId, &name](const auto &key, const auto &value) -> bool { - if (value != nullptr && *value == connId) { - name += key; - name += " "; - return true; + connects_.ForEach([connId, &name](const auto &deviceId, auto &connects) -> bool { + for (auto iter = connects.begin(); iter != connects.end();) { + if (*iter != nullptr && **iter == connId) { + name += deviceId; + name += " "; + iter = connects.erase(iter); + } else { + iter++; + } } return false; }); @@ -305,9 +338,11 @@ void SoftBusAdapter::OnSessionOpen(int32_t connId, int32_t status) if (status != SOFTBUS_OK) { return; } - connects_.ForEach([connId](const auto &key, const auto &value) -> bool { - if (value != nullptr && *value == connId) { - value->UpdateExpireTime(); + connects_.ForEach([connId](const auto &key, auto &connects) -> bool { + for (auto conn : connects) { + if (conn != nullptr && *conn == connId) { + conn->UpdateExpireTime(); + } } return false; }); @@ -497,32 +532,26 @@ void AppDataListenerWrap::NotifyDataListeners(const uint8_t *data, const int siz softBusAdapter_->NotifyDataListeners(data, size, deviceId, pipeInfo); } -void SoftBusAdapter::SofBusDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, +void SoftBusAdapter::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const { - Strategy strategy = Strategy::BUTT; + if (info.uuid == DmAdapter::CLOUD_DEVICE_UUID) { + return; + } + switch (type) { case AppDistributedKv::DeviceChangeType::DEVICE_ONLINE: - strategy = Strategy::ON_LINE_SELECT_CHANNEL; + CommunicationStrategy::GetInstance().SetStrategy(info.uuid, Strategy::ON_LINE_SELECT_CHANNEL); + break; + case AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE: + CommunicationStrategy::GetInstance().RemoveStrategy(info.uuid); break; case AppDistributedKv::DeviceChangeType::DEVICE_ONREADY: - strategy = Strategy::DEFAULT; + CommunicationStrategy::GetInstance().SetStrategy(info.uuid, Strategy::DEFAULT); break; default: break; } - - if (strategy >= Strategy::BUTT) { - return; - } - - CommunicationStrategy::GetInstance().SetStrategy(info.uuid, strategy, - [this](const std::string &deviceId, Strategy strategy) { - std::shared_ptr conn = SoftBusAdapter::GetInstance()->GetConnect(deviceId); - if (conn != nullptr) { - conn->AfterStrategyUpdate(strategy); - } - }); } } // namespace AppDistributedKv } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp index 6a6d5bee..73192d63 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -54,7 +54,6 @@ void SoftBusClient::RestoreDefaultValue() connId_ = INVALID_CONNECT_ID; status_ = ConnectStatus::DISCONNECT; routeType_ = RouteType::INVALID_ROUTE_TYPE; - strategy_ = Strategy::DEFAULT; mtu_ = DEFAULT_MTU_SIZE; } @@ -93,102 +92,46 @@ Status SoftBusClient::Send(const DataInfo &dataInfo, uint32_t totalLength) if (result != Status::SUCCESS) { return result; } - expireTime_ = std::chrono::steady_clock::now() + GetDelayTime(totalLength); + ZLOGD("send data connId:%{public}d, data size:%{public}u, total length:%{public}u.", connId_, dataInfo.length, totalLength); int32_t ret = SendBytes(connId_, dataInfo.data, dataInfo.length); if (ret != SOFTBUS_OK) { + expireTime_ = std::chrono::steady_clock::now(); ZLOGE("send data to connId%{public}d failed, ret:%{public}d.", connId_, ret); return Status::ERROR; } + expireTime_ = std::chrono::steady_clock::now() + GetDelayTime(totalLength); return Status::SUCCESS; } -Status SoftBusClient::OpenConnect(uint32_t totalLength) -{ - strategy_ = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); - if (status_ == ConnectStatus::CONNECT_OK) { - status_ = ConnectStatus::DISCONNECT; - auto result = SwitchChannel(totalLength); - if (result == Status::SUCCESS) { - status_ = ConnectStatus::CONNECT_OK; - } - return result; - } - if (routeType_ == RouteType::INVALID_ROUTE_TYPE) { - return CreateChannel(totalLength); - } - status_ = ConnectStatus::CONNECT_OK; - return Status::SUCCESS; -} - -Status SoftBusClient::SwitchChannel(uint32_t totalLength) +Status SoftBusClient::OpenConnect(uint32_t length) { - if (strategy_ == Strategy::BUTT) { - return Status::NETWORK_ERROR; - } - - if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { - return Status::SUCCESS; - } - - if (routeType_ == RouteType::WIFI_STA) { + auto strategy = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); + if (routeType_ != RouteType::INVALID_ROUTE_TYPE) { return Status::SUCCESS; } - - if (routeType_ == RouteType::BT_BLE || routeType_ == RouteType::BT_BR) { - if (totalLength < P2P_SIZE_THRESHOLD) { - return Status::SUCCESS; - } - - ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to wifi or p2p.", - KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); - RestoreDefaultValue(); - return OpenSessionByAsync(GetSessionAttribute(true)); - } - - if (routeType_ == RouteType::WIFI_P2P) { - if (totalLength > P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR) { - return Status::SUCCESS; - } - - ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to ble or br.", - KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); - RestoreDefaultValue(); - return OpenSessionByAsync(GetSessionAttribute(false)); - } - - return Status::NETWORK_ERROR; -} - -Status SoftBusClient::CreateChannel(uint32_t totalLength) -{ - if (strategy_ == Strategy::BUTT) { + if (strategy == Strategy::BUTT) { return Status::NETWORK_ERROR; } - if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { - return OpenSessionByAsync(GetSessionAttribute(true)); - } - if (totalLength < P2P_SIZE_THRESHOLD) { - return OpenSessionByAsync(GetSessionAttribute(false)); - } - return OpenSessionByAsync(GetSessionAttribute(true)); -} -Status SoftBusClient::OpenSessionByAsync(SessionAttribute attr) -{ - auto openSessionTask = [attr, client = shared_from_this()]() { + bool expireP2P = strategy == Strategy::ON_LINE_SELECT_CHANNEL || length >= P2P_SIZE_THRESHOLD; + expireType_ = expireP2P ? RouteType::WIFI_P2P : RouteType::BT_BLE; + auto attr = GetSessionAttribute(expireP2P); + auto task = [attr, client = shared_from_this()]() { if (client == nullptr) { ZLOGE("OpenSessionByAsync client is nullptr."); return; } + ZLOGI("OpenSession Start."); (void)client->Open(attr); client->sessionFlag_.store(false); }; + if (sessionFlag_.exchange(true)) { return Status::RATE_LIMIT; } - Context::GetInstance().GetThreadPool()->Execute(openSessionTask); + Context::GetInstance().GetThreadPool()->Execute(task); return Status::RATE_LIMIT; } @@ -196,16 +139,16 @@ Status SoftBusClient::Open(SessionAttribute attr) { int id = OpenSession(pipe_.pipeId.c_str(), pipe_.pipeId.c_str(), DmAdapter::GetInstance().ToNetworkID(device_.deviceId).c_str(), "GROUP_ID", &attr); - ZLOGI("open %{public}s,session:%{public}s,connId:%{public}d,linkNum:%{public}d,strategy:%{public}d", - KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), id, attr.linkTypeNum, strategy_); + ZLOGI("open %{public}s,session:%{public}s,connId:%{public}d,linkNum:%{public}d,datatype:%{public}d", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), + id, attr.linkTypeNum, attr.dataType); if (id < 0) { ZLOGW("Open %{public}s, type:%{public}d failed, connId:%{public}d", pipe_.pipeId.c_str(), attr.dataType, id); return Status::NETWORK_ERROR; } - connId_ = id; - int state = getConnStatus_(connId_); + int state = getConnStatus_(id); ZLOGI("waited for notification, state:%{public}d connId:%{public}d", state, id); if (state != SOFTBUS_OK) { ZLOGE("open callback result error"); @@ -213,14 +156,23 @@ Status SoftBusClient::Open(SessionAttribute attr) } int32_t routeType = RouteType::INVALID_ROUTE_TYPE; - auto ret = GetSessionOption(connId_, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); - if (ret != SOFTBUS_OK) { - ZLOGE("get routeType failed, session:%{public}s, connId:%{public}d", pipe_.pipeId.c_str(), connId_); + std::tie(state, routeType) = GetRouteType(id); + if (state != SOFTBUS_OK) { + ZLOGE("GetRouteType failed, session:%{public}s, connId:%{public}d", pipe_.pipeId.c_str(), id); return Status::NETWORK_ERROR; } - routeType_ = routeType; - - UpdateMtuSize(); + uint32_t mtu = 0; + std::tie(state, mtu) = GetMtu(id); + if (state != SOFTBUS_OK) { + ZLOGE("GetMtu failed, session:%{public}s, connId:%{public}d", pipe_.pipeId.c_str(), id); + return Status::NETWORK_ERROR; + } + { + std::lock_guard lock(mutex_); + connId_ = id; + routeType_ = routeType; + mtu_ = mtu; + } ZLOGI("open %{public}s, session:%{public}s success, connId:%{public}d, routeType:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); return Status::SUCCESS; @@ -244,28 +196,23 @@ SessionAttribute SoftBusClient::GetSessionAttribute(bool isP2p) return attr; } -void SoftBusClient::UpdateMtuSize() +std::pair SoftBusClient::GetRouteType(int32_t id) { - uint32_t mtu = 0; - auto result = GetSessionOption(connId_, SESSION_OPTION_MAX_SENDBYTES_SIZE, &mtu, sizeof(mtu)); - if (result != SOFTBUS_OK) { - return; - } - mtu_ = mtu; + int32_t routeType = RouteType::INVALID_ROUTE_TYPE; + auto ret = GetSessionOption(id, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + return { ret, routeType }; } -void SoftBusClient::AfterStrategyUpdate(Strategy strategy) +std::pair SoftBusClient::GetMtu(int32_t id) { - std::lock_guard lock(mutex_); - if (strategy != strategy_ && connId_ > 0) { - ZLOGI("close connId:%{public}d,strategy current:%{public}d, new:%{public}d", connId_, strategy_, strategy); - CloseSession(connId_); - RestoreDefaultValue(); - } + uint32_t mtu = 0; + auto ret = GetSessionOption(id, SESSION_OPTION_MAX_SENDBYTES_SIZE, &mtu, sizeof(mtu)); + return { ret, mtu }; } SoftBusClient::Time SoftBusClient::GetExpireTime() const { + std::lock_guard lock(mutex_); return expireTime_; } @@ -281,7 +228,11 @@ int32_t SoftBusClient::GetRoutType() const void SoftBusClient::UpdateExpireTime() { - expireTime_ = std::chrono::steady_clock::now() + GetDelayTime(0); + auto expireTime = std::chrono::steady_clock::now() + GetDelayTime(0); + std::lock_guard lock(mutex_); + if (expireTime > expireTime_) { + expireTime_ = expireTime; + } } SoftBusClient::Duration SoftBusClient::GetDelayTime(uint32_t dataLength) @@ -291,4 +242,26 @@ SoftBusClient::Duration SoftBusClient::GetDelayTime(uint32_t dataLength) } return SESSION_CLOSE_DELAY; } + +bool SoftBusClient::Support(uint32_t length) const +{ + auto strategy = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); + if (strategy == Strategy::ON_LINE_SELECT_CHANNEL) { + return true; + } + + std::lock_guard lock(mutex_); + if (routeType_ == RouteType::WIFI_STA || routeType_ == RouteType::INVALID_ROUTE_TYPE) { + return true; + } + + if (routeType_ == RouteType::BT_BLE || routeType_ == RouteType::BT_BR) { + return expireType_ == RouteType::WIFI_P2P || length < P2P_SIZE_THRESHOLD; + } + + if (routeType_ == RouteType::WIFI_P2P) { + return (length > P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR); + } + return true; +} } \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h index 16ff0893..6c99d509 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -44,22 +44,20 @@ public: Time GetExpireTime() const; int32_t GetConnId() const; int32_t GetRoutType() const; + bool Support(uint32_t length) const; void UpdateExpireTime(); - void AfterStrategyUpdate(Strategy strategy); private: enum class ConnectStatus : int32_t { CONNECT_OK, DISCONNECT, }; - Status OpenConnect(uint32_t totalLength); - Status SwitchChannel(uint32_t totalLength); - Status CreateChannel(uint32_t totalLength); + Status OpenConnect(uint32_t length); Status Open(SessionAttribute attr); - Status OpenSessionByAsync(SessionAttribute attr); SessionAttribute GetSessionAttribute(bool isP2p); void RestoreDefaultValue(); - void UpdateMtuSize(); + std::pair GetMtu(int32_t id); + std::pair GetRouteType(int32_t id); Duration GetDelayTime(uint32_t dataLength); static constexpr int32_t INVALID_CONNECT_ID = -1; @@ -71,18 +69,19 @@ private: static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB static constexpr uint32_t P2P_TRANSFER_PER_MICROSECOND = 3; // 2^3 bytes per microsecond static constexpr float SWITCH_DELAY_FACTOR = 0.6f; - static constexpr Duration SESSION_CLOSE_DELAY = std::chrono::seconds(60); + static constexpr Duration SESSION_CLOSE_DELAY = std::chrono::seconds(150); + static constexpr Duration SESSION_OPEN_DELAY = std::chrono::seconds(20); std::atomic_bool sessionFlag_ = false; int32_t connId_ = INVALID_CONNECT_ID; int32_t routeType_ = RouteType::INVALID_ROUTE_TYPE; - Strategy strategy_ = Strategy::DEFAULT; + int32_t expireType_ = RouteType::INVALID_ROUTE_TYPE; ConnectStatus status_ = ConnectStatus::DISCONNECT; - std::mutex mutex_; + mutable std::mutex mutex_; PipeInfo pipe_; DeviceId device_; uint32_t mtu_; std::function getConnStatus_; - Time expireTime_ = std::chrono::steady_clock::now(); + Time expireTime_ = std::chrono::steady_clock::now() + SESSION_OPEN_DELAY; }; } diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_strategy.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_strategy.h index de747e15..5b8b1696 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_strategy.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_strategy.h @@ -35,8 +35,8 @@ public: using Strategy = CommunicationStrategy::Strategy; void RegGetSyncDataSize(const std::string &type, const std::function &getDataSize); CommunicationStrategy::Strategy GetStrategy(const std::string &deviceId); - void SetStrategy(const std::string &deviceId, Strategy strategy, - const std::function &action); + void SetStrategy(const std::string &deviceId, Strategy strategy); + void RemoveStrategy(const std::string &deviceId); private: CommunicationStrategy() = default; ~CommunicationStrategy() = default; @@ -53,4 +53,4 @@ private: }; } -#endif // DISTRIBUTEDDATAMGR_DATAMGR_SERVICE_COMMUNICATION_STRATEGY_H +#endif // DISTRIBUTEDDATAMGR_DATAMGR_SERVICE_COMMUNICATION_STRATEGY_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h index a32eefbc..f77f374a 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h @@ -37,6 +37,7 @@ public: using PipeInfo = OHOS::AppDistributedKv::PipeInfo; using AppDeviceChangeListener = OHOS::AppDistributedKv::AppDeviceChangeListener; using Status = OHOS::DistributedKv::Status; + using Time = std::chrono::steady_clock::time_point; static DeviceManagerAdapter &GetInstance(); static constexpr const char *CLOUD_DEVICE_UUID = "cloudDeviceUuid"; static constexpr const char *CLOUD_DEVICE_UDID = "cloudDeviceUdid"; @@ -65,6 +66,7 @@ private: ~DeviceManagerAdapter(); std::function RegDevCallback(); bool RegOnNetworkChange(); + bool SetNetAvailable(bool isNetAvailable); bool GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo &dvInfo); void SaveDeviceInfo(const DeviceInfo &deviceInfo, const AppDistributedKv::DeviceChangeType &type); void UpdateDeviceInfo(); @@ -85,6 +87,9 @@ private: static constexpr int32_t SYNC_TIMEOUT = 30 * 1000; // ms ConcurrentMap syncTask_ {}; std::shared_ptr executors_; + mutable std::shared_mutex mutex_; + static constexpr int32_t EFFECTIVE_DURATION = 30 * 1000; // ms + Time expireTime_ = std::chrono::steady_clock::now(); bool isNetAvailable_ = false; }; } // namespace DistributedData diff --git a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg index b980a16e..03a59d77 100644 --- a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg +++ b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg @@ -35,7 +35,8 @@ "ohos.permission.ACCESS_SERVICE_DM", "ohos.permission.PROXY_AUTHORIZATION_URI", "ohos.permission.CLOUDFILE_SYNC", - "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT" + "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT", + "ohos.permission.GET_BUNDLE_INFO" ] } ] diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer.cpp b/datamgr_service/services/distributeddataservice/app/src/installer/installer.cpp index d3eccd6b..25969221 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer.cpp @@ -19,7 +19,7 @@ namespace OHOS::DistributedKv { Installer &Installer::GetInstance() { - static InstallerImpl Installer; - return Installer; + static InstallerImpl installer; + return installer; } } // namespace OHOS::DistributedKv diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 349e4d4f..2614d2d6 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -230,13 +230,16 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() dbStatusTmp = dbStatus; }); - if (dbStatusTmp != DistributedDB::DBStatus::OK) { - ZLOGE("GetKvStore return error status: %{public}d", static_cast(dbStatusTmp)); + if (dbStatusTmp != DistributedDB::DBStatus::OK || delegate == nullptr) { + ZLOGE("GetKvStore return error status: %{public}d or delegate is nullptr", static_cast(dbStatusTmp)); return nullptr; } delegate->SetRemotePushFinishedNotify([](const RemotePushNotifyInfo &info) { DeviceMatrix::GetInstance().OnExchanged(info.deviceId, DeviceMatrix::META_STORE_MASK); }); + bool param = true; + auto data = static_cast(¶m); + delegate->Pragma(DistributedDB::SET_SYNC_RETRY, data); auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) { ZLOGI("release meta data kv store"); if (delegate == nullptr) { diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index 474aed8a..760ac9c5 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -47,6 +47,7 @@ ohos_shared_library("distributeddatasvcfwk") { "cloud/asset_loader.cpp", "cloud/cloud_db.cpp", "cloud/cloud_event.cpp", + "cloud/cloud_extra_data.cpp", "cloud/cloud_info.cpp", "cloud/cloud_server.cpp", "cloud/cloud_share_event.cpp", @@ -74,6 +75,8 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/strategy_meta_data.cpp", "metadata/user_meta_data.cpp", "serializable/serializable.cpp", + "snapshot/bind_event.cpp", + "snapshot/snapshot.cpp", "store/auto_cache.cpp", "utils/anonymous.cpp", "utils/block_integer.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt index 8819ada0..4bcc25a0 100644 --- a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt @@ -16,6 +16,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dump svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/metadata svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/eventcenter svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/serializable svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/snapshot svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/feature svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/directory svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/store svcFwkSrc) diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp index b819260e..f7dd8ac0 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp @@ -34,11 +34,12 @@ bool SchemaMeta::Unmarshal(const Serializable::json &node) std::vector Database::GetTableNames() const { std::vector tableNames; - auto sharedTableSize = tables.size(); - tableNames.reserve(tables.size() + sharedTableSize); - for (auto &table : tables) { + tableNames.reserve(tables.size()); + for (auto& table : tables) { tableNames.push_back(table.name); - tableNames.push_back(table.sharedTableName); + if (!table.sharedTableName.empty()) { + tableNames.push_back(table.sharedTableName); + } } return tableNames; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h index 8571619f..a6b0e25b 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h @@ -26,7 +26,7 @@ public: enum Role { ROLE_NIL = -1, ROLE_INVITER, - ROLE_INVITEES, + ROLE_INVITEE, ROLE_BUTT }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h index 28d7fdb6..b8850153 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h +++ b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h @@ -35,6 +35,7 @@ enum GeneralError : int32_t { E_PARTIAL_ERROR, E_USER_UNLOCK, E_VERSION_CONFLICT, + E_RECORD_EXIST_CONFLICT, E_BUTT, }; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h index 4c529ff6..4f1772e0 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -22,6 +22,7 @@ #include "store/cursor.h" #include "store/general_value.h" #include "store/general_watcher.h" +#include "snapshot/snapshot.h" namespace OHOS::DistributedData { class CloudDB; class AssetLoader; @@ -122,6 +123,10 @@ public: virtual int32_t AddRef() = 0; virtual int32_t Release() = 0; + + virtual int32_t BindSnapshots(std::shared_ptr>> bindAssets) = 0; + + virtual int32_t MergeMigratedData(const std::string &tableName, VBuckets&& values) = 0; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index c5d560af..e884ee7c 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -27,6 +27,7 @@ config("module_public_config") { "backup/include", "bootstrap/include", "cloud", + "common", "config/include", "crypto/include", "dumper/include", @@ -48,13 +49,17 @@ config("module_public_config") { "${kv_store_distributeddb_path}/include/", "${kv_store_distributeddb_path}/interfaces/include/", "${kv_store_distributeddb_path}/interfaces/include/relational", + "${dataobject_path}/interfaces/innerkits", ] } ohos_shared_library("distributeddatasvc") { include_dirs = [ - "../../../../data_object/frameworks/innerkitsimpl/include", + "${dataobject_path}/frameworks/innerkitsimpl/include", + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", "../../../../relational_store/interfaces/inner_api/cloud_data/include", + "../../../../relational_store/interfaces/inner_api/common_type/include", "../../../../relational_store/interfaces/inner_api/rdb/include", "${kv_store_distributeddb_path}", ] @@ -66,6 +71,7 @@ ohos_shared_library("distributeddatasvc") { "cloud/cloud_types_util.cpp", "cloud/cloud_value_util.cpp", "cloud/sync_manager.cpp", + "common/value_proxy.cpp", "config/src/config_factory.cpp", "config/src/model/backup_config.cpp", "config/src/model/checker_config.cpp", @@ -87,11 +93,15 @@ ohos_shared_library("distributeddatasvc") { "kvdb/user_delegate.cpp", "matrix/src/device_matrix.cpp", "matrix/src/matrix_event.cpp", + "object/object_asset_loader.cpp", + "object/object_asset_machine.cpp", "object/object_callback_proxy.cpp", "object/object_data_listener.cpp", "object/object_manager.cpp", "object/object_service_impl.cpp", "object/object_service_stub.cpp", + "object/object_snapshot.cpp", + "object/object_types_utils.cpp", "permission/src/permit_delegate.cpp", "rdb/cache_cursor.cpp", "rdb/rdb_asset_loader.cpp", @@ -106,7 +116,6 @@ ohos_shared_library("distributeddatasvc") { "rdb/rdb_service_impl.cpp", "rdb/rdb_service_stub.cpp", "rdb/rdb_watcher.cpp", - "rdb/value_proxy.cpp", ] cflags = [ "-Wno-multichar", @@ -129,11 +138,13 @@ ohos_shared_library("distributeddatasvc") { "c_utils:utils", "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", + "dfs_service:cloudsync_asset_kit_inner", "hilog:libhilog", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddb", + "relational_store:common_type", "relational_store:native_rdb", ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt index 86648550..d1104cb4 100644 --- a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt @@ -14,6 +14,7 @@ set(KV_STORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../kv_store") aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/backup/src serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/src serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/cloud serviceSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/common serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/config/src serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/config/src/model serviceSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/crypto/src serviceSrc) @@ -40,6 +41,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/permission/src serviceSrc) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backup/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/config/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/crypto/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/permission/include) @@ -60,6 +62,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../framework/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../app/src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../kv_store/frameworks/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../relational_store/interfaces/inner_api/rdb/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../relational_store/interfaces/inner_api/common_type/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../data_share/frameworks/native/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../data_share/frameworks/native/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../data_object/frameworks/innerkitsimpl/include) @@ -70,7 +73,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/base/in include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/safwk/native/include) include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) -set(links secure mock kvdb svcFwk adapter data_share udmf gaussdb cloud_data relational_store) +set(links secure mock kvdb svcFwk adapter data_share udmf gaussdb cloud_data relational_store data_object) set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/../../../") add_library(service SHARED ${serviceSrc}) target_link_libraries(service ${links}) diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index 4ec6201e..99138481 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -176,7 +176,7 @@ int32_t CloudServiceImpl::DoClean(CloudInfo &cloudInfo, const std::mapClean({}, action, ""); if (status != E_OK) { - ZLOGW("remove device data status:%{public}d, user:%{pubilc}d, bundleName:%{public}s, " + ZLOGW("remove device data status:%{public}d, user:%{public}d, bundleName:%{public}s, " "storeId:%{public}s", status, static_cast(cloudInfo.user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); continue; @@ -229,29 +229,32 @@ int32_t CloudServiceImpl::CheckNotifyConditions(const std::string &id, const std return SUCCESS; } -int32_t CloudServiceImpl::GetDbInfoFromExtraData(const ExtraData &exData, int32_t userId, std::string &storeId, - std::vector &table) +std::pair> CloudServiceImpl::GetDbInfoFromExtraData( + const DistributedData::ExtraData &extraData, const SchemaMeta &schemaMeta) { - auto schemaKey = CloudInfo::GetSchemaKey(userId, exData.extInfo.bundleName); - SchemaMeta schemaMeta; - if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { - ZLOGE("no exist meta, user:%{public}d", userId); - return ERROR; - } + std::string storeId; + std::vector names; for (auto &db : schemaMeta.databases) { - if (db.alias != exData.extInfo.containerName) { + if (db.alias != extraData.info.containerName) { continue; } storeId = db.name; for (auto &tb : db.tables) { - const auto &tbs = exData.extInfo.tables; + const auto &tbs = extraData.info.tables; if (std::find(tbs.begin(), tbs.end(), tb.alias) == tbs.end()) { continue; } - table.emplace_back(tb.name); + if (extraData.isPrivate()) { + ZLOGD("private table change, name:%{public}s", Anonymous::Change(tb.name).c_str()); + names.emplace_back(tb.name); + } + if (extraData.isShared() && !tb.sharedTableName.empty()) { + ZLOGD("sharing table change, name:%{public}s", Anonymous::Change(tb.sharedTableName).c_str()); + names.emplace_back(tb.sharedTableName); + } } } - return SUCCESS; + return { storeId, names }; } int32_t CloudServiceImpl::NotifyDataChange(const std::string &id, const std::string &bundleName) @@ -287,15 +290,17 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &eventId, const std continue; } auto [status, cloudInfo] = GetCloudInfoFromMeta(user); - if (CheckNotifyConditions(exData.extInfo.accountId, exData.extInfo.bundleName, cloudInfo) != E_OK) { + if (CheckNotifyConditions(exData.info.accountId, exData.info.bundleName, cloudInfo) != E_OK) { return INVALID_ARGUMENT; } - std::string storeId; - std::vector table; - if (GetDbInfoFromExtraData(exData, userId, storeId, table) != E_OK) { + auto schemaKey = CloudInfo::GetSchemaKey(user, exData.info.bundleName); + SchemaMeta schemaMeta; + if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { + ZLOGE("no exist meta, user:%{public}d", user); return INVALID_ARGUMENT; } - syncManager_.DoCloudSync(SyncManager::SyncInfo(cloudInfo.user, exData.extInfo.bundleName, storeId, table)); + auto [storeId, tables] = GetDbInfoFromExtraData(exData, schemaMeta); + syncManager_.DoCloudSync(SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, storeId, tables)); } return SUCCESS; } @@ -754,7 +759,7 @@ std::pair> CloudServiceImpl::Alloc Results results; for (auto& valueBucket : valueBuckets) { NativeRdb::ValueObject object; - if (!valueBucket.GetObject(SchemaMeta::SHARING_RESOURCE, object)) { + if (!valueBucket.GetObject(DistributedRdb::Field::SHARING_RESOURCE_FIELD, object)) { continue; } std::string shareRes; @@ -807,38 +812,6 @@ std::pair CloudServiceImpl::GetHapInfo(uint32_t tokenId) return { tokenInfo.bundleName, tokenInfo.instIndex }; } -bool CloudServiceImpl::ExtraData::Marshal(Serializable::json &node) const -{ - SetValue(node[GET_NAME(header)], header); - SetValue(node[GET_NAME(data)], data); - return true; -} - -bool CloudServiceImpl::ExtraData::Unmarshal(const Serializable::json &node) -{ - GetValue(node, GET_NAME(header), header); - GetValue(node, GET_NAME(data), data); - return extInfo.Unmarshall(data); -} - -bool CloudServiceImpl::ExtraData::ExtInfo::Marshal(Serializable::json &node) const -{ - SetValue(node[GET_NAME(accountId)], accountId); - SetValue(node[GET_NAME(bundleName)], bundleName); - SetValue(node[GET_NAME(containerName)], containerName); - SetValue(node[GET_NAME(recordTypes)], recordTypes); - return true; -} - -bool CloudServiceImpl::ExtraData::ExtInfo::Unmarshal(const Serializable::json &node) -{ - GetValue(node, GET_NAME(accountId), accountId); - GetValue(node, GET_NAME(bundleName), bundleName); - GetValue(node, GET_NAME(containerName), containerName); - GetValue(node, GET_NAME(recordTypes), recordTypes); - return Unmarshall(recordTypes, tables); -} - int32_t CloudServiceImpl::Share( const std::string &sharingRes, const Participants &participants, Results &results) { diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h index c1cfdc48..b2032abb 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -19,6 +19,7 @@ #include #include #include "cloud/cloud_event.h" +#include "cloud/cloud_extra_data.h" #include "cloud/cloud_info.h" #include "cloud/schema_meta.h" #include "cloud/subscription.h" @@ -86,23 +87,6 @@ private: using Handles = std::deque; using Task = ExecutorPool::Task; - struct ExtraData final : public DistributedData::Serializable { - struct ExtInfo final : public Serializable { - std::string accountId; - std::string bundleName; - std::string containerName; - std::string recordTypes; - std::vector tables; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; - }; - std::string header; - std::string data; - ExtInfo extInfo; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; - }; - static std::map ConvertAction(const std::map &actions); static std::pair GetHapInfo(uint32_t tokenId); @@ -111,7 +95,7 @@ private: static constexpr int32_t EXPIRE_INTERVAL = 2 * 24; // 2 day static constexpr int32_t WAIT_TIME = 30; // 30 seconds static constexpr int32_t DEFAULT_USER = 0; - static constexpr const char *DATA_CHANGE_EVENT_ID = "cloud_data_change"; + struct HapInfo { int32_t user; std::string bundleName; @@ -142,8 +126,8 @@ private: DistributedData::GenQuery& query); std::vector ConvertCursor(std::shared_ptr cursor) const; int32_t CheckNotifyConditions(const std::string &id, const std::string &bundleName, CloudInfo &cloudInfo); - int32_t GetDbInfoFromExtraData(const ExtraData &exData, int32_t userId, std::string &storeId, - std::vector &table); + std::pair> GetDbInfoFromExtraData( + const DistributedData::ExtraData &extraData, const SchemaMeta &schemaMeta); std::pair, HapInfo> GetSharingHandle(); std::shared_ptr executor_; SyncManager syncManager_; diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/store_cache.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/store_cache.cpp index 3f9059e8..3fb0945f 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/store_cache.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/store_cache.cpp @@ -58,6 +58,9 @@ StoreCache::Store StoreCache::GetStore(const StoreMetaData &data, std::shared_pt dbStore->SetRemotePushFinishedNotify([code](const DistributedDB::RemotePushNotifyInfo &info) { DeviceMatrix::GetInstance().OnExchanged(info.deviceId, code, true); }); + bool param = true; + auto data = static_cast(¶m); + dbStore->Pragma(DistributedDB::SET_SYNC_RETRY, data); } auto result = stores.emplace(std::piecewise_construct, std::forward_as_tuple(data.storeId), diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp index 9f46f2fe..12cbd9ec 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp @@ -17,12 +17,16 @@ #include "object_manager.h" +#include "ipc_skeleton.h" +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" #include "bootstrap.h" #include "checker/checker_manager.h" #include "datetime_ex.h" #include "kvstore_utils.h" #include "log_print.h" #include "object_data_listener.h" +#include "object_asset_loader.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "account/account_delegate.h" @@ -30,9 +34,13 @@ namespace OHOS { namespace DistributedObject { using namespace OHOS::DistributedKv; +using namespace Security::AccessToken; using StoreMetaData = OHOS::DistributedData::StoreMetaData; using AccountDelegate = DistributedKv::AccountDelegate; - +using OHOS::DistributedKv::AccountDelegate; +using Account = OHOS::DistributedKv::AccountDelegate; +using AccessTokenKit = Security::AccessToken::AccessTokenKit; +using ValueProxy = OHOS::DistributedData::ValueProxy; ObjectStoreManager::ObjectStoreManager() {} DistributedDB::KvStoreNbDelegate *ObjectStoreManager::OpenObjectKvStore() @@ -710,5 +718,101 @@ SequenceSyncManager::Result SequenceSyncManager::DeleteNotifierNoLock(uint64_t s } return SUCCESS_USER_HAS_FINISHED; } + +int32_t ObjectStoreManager::BindAsset(const uint32_t tokenId, const std::string& appId, const std::string& sessionId, + ObjectStore::Asset& asset, ObjectStore::AssetBindInfo& bindInfo) +{ + auto snapshotKey = appId + SEPERATOR + sessionId; + snapshots_.ComputeIfAbsent( + snapshotKey, [](const std::string& key) -> auto { + return std::make_shared(); + }); + auto storeKey = appId + SEPERATOR + bindInfo.storeName; + bindSnapshots_.ComputeIfAbsent( + storeKey, [](const std::string& key) -> auto { + return std::make_shared>>(); + }); + bindSnapshots_[storeKey]->emplace(std::pair{asset.uri, snapshots_[snapshotKey]}); + + HapTokenInfo tokenInfo; + auto status = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (status != RET_SUCCESS) { + ZLOGE("token:0x%{public}x, result:%{public}d, bundleName:%{public}s", tokenId, status, appId.c_str()); + return GeneralError::E_ERROR; + } + StoreInfo storeInfo; + storeInfo.bundleName = appId; + storeInfo.tokenId = tokenId; + storeInfo.instanceId = tokenInfo.instIndex; + storeInfo.user = tokenInfo.userID; + storeInfo.storeName = bindInfo.storeName; + + snapshots_[snapshotKey]->BindAsset(ValueProxy::Convert(std::move(asset)), ConvertBindInfo(bindInfo), storeInfo); + return OBJECT_SUCCESS; +} + +DistributedData::AssetBindInfo ObjectStoreManager::ConvertBindInfo(ObjectStore::AssetBindInfo& bindInfo) +{ + return DistributedData::AssetBindInfo{ + .storeName = std::move(bindInfo.storeName), + .tableName = std::move(bindInfo.tableName), + .primaryKey = ValueProxy::Convert(std::move(bindInfo.primaryKey)), + .field = std::move(bindInfo.field), + .assetName = std::move(bindInfo.assetName), + }; +} + +int32_t ObjectStoreManager::OnAssetChanged(const uint32_t tokenId, const std::string& appId, + const std::string& sessionId, const std::string& deviceId, const ObjectStore::Asset& asset) +{ + const int32_t userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); + auto objectAsset = asset; + Asset dataAsset = ValueProxy::Convert(std::move(objectAsset)); + auto snapshotKey = appId + SEPERATOR + sessionId; + if (snapshots_.Contains(snapshotKey) && snapshots_[snapshotKey]->IsBoundAsset(dataAsset)) { + return snapshots_[snapshotKey]->OnDataChanged(dataAsset, deviceId); // needChange + } + + bool isSuccess = ObjectAssetLoader::GetInstance()->DownLoad(userId, appId, deviceId, dataAsset); + if (isSuccess) { + return OBJECT_SUCCESS; + } else { + ZLOGE("DownLoad fail, userId: %{public}d, bundleName: %{public}s, networkId: %{public}s, asset name : " + "%{public}s", userId, appId.c_str(), deviceId.c_str(), asset.name.c_str()); + return OBJECT_INNER_ERROR; + } +} + +ObjectStoreManager::UriToSnapshot ObjectStoreManager::GetSnapShots(const std::string& bundleName, + const std::string& storeName) +{ + auto storeKey = bundleName + SEPERATOR + storeName; + bindSnapshots_.ComputeIfAbsent( + storeKey, [](const std::string& key) -> auto { + return std::make_shared>>(); + }); + return bindSnapshots_[storeKey]; +} + +void ObjectStoreManager::DeleteSnapshot(const std::string& bundleName, const std::string& sessionId) +{ + auto snapshotKey = bundleName + SEPERATOR + sessionId; + if (!snapshots_.Contains(snapshotKey)) { + ZLOGD("Not find snapshot, don't need delete"); + return; + } + auto snapshot = snapshots_[snapshotKey]; + bindSnapshots_.ForEach([snapshot](auto& key, auto& value) { + for (auto pos = value->begin(); pos != value->end();) { + if (pos->second == snapshot) { + pos = value->erase(pos); + } else { + ++pos; + } + } + return true; + }); + snapshots_.Erase(snapshotKey); +} } // namespace DistributedObject } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.h b/datamgr_service/services/distributeddataservice/service/object/object_manager.h index 7cd1a992..c73d475d 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.h @@ -27,6 +27,9 @@ #include "object_common.h" #include "object_data_listener.h" #include "types.h" +#include "object_snapshot.h" +#include "object_types.h" +#include "value_proxy.h" namespace OHOS { namespace DistributedObject { @@ -68,6 +71,7 @@ private: class ObjectStoreManager { public: using DmAdaper = OHOS::DistributedData::DeviceManagerAdapter; + using UriToSnapshot = std::shared_ptr>>; ObjectStoreManager(); static ObjectStoreManager *GetInstance() { @@ -92,6 +96,12 @@ public: void CloseAfterMinute(); int32_t Open(); void SetThreadPool(std::shared_ptr executors); + UriToSnapshot GetSnapShots(const std::string &bundleName, const std::string &storeName); + int32_t BindAsset(const uint32_t tokenId, const std::string& appId, const std::string& sessionId, + ObjectStore::Asset& asset, ObjectStore::AssetBindInfo& bindInfo); + int32_t OnAssetChanged(const uint32_t tokenId, const std::string& appId, const std::string& sessionId, + const std::string& deviceId, const ObjectStore::Asset& asset); + void DeleteSnapshot(const std::string &bundleName, const std::string &sessionId); private: constexpr static const char *SEPERATOR = "_"; constexpr static const char *LOCAL_DEVICE = "local"; @@ -161,6 +171,10 @@ private: static constexpr size_t TIME_TASK_NUM = 1; static constexpr int64_t INTERVAL = 1; std::shared_ptr executors_; + DistributedData::AssetBindInfo ConvertBindInfo(ObjectStore::AssetBindInfo& bindInfo); + VBucket ConvertVBucket(ObjectStore::ValuesBucket &vBucket); + ConcurrentMap> snapshots_; // key:bundleName_sessionId + ConcurrentMap bindSnapshots_; // key:bundleName_storeName }; } // namespace DistributedObject } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index b877d4b5..75dce52d 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -25,11 +25,14 @@ #include "device_manager_adapter.h" #include "directory/directory_manager.h" #include "dump/dump_manager.h" +#include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "permission/permission_validator.h" +#include "snapshot/bind_event.h" +#include "store/auto_cache.h" #include "utils/anonymous.h" namespace OHOS::DistributedObject { @@ -75,6 +78,38 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const return status; } +int32_t ObjectServiceImpl::OnAssetChanged(const std::string &bundleName, const std::string &sessionId, + const std::string &deviceId, const ObjectStore::Asset &assetValue) +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + ZLOGE("OnAssetChanged object bundleName wrong, status %{public}d", status); + return status; + } + status = ObjectStoreManager::GetInstance()->OnAssetChanged(tokenId, bundleName, sessionId, deviceId, assetValue); + if (status != OBJECT_SUCCESS) { + ZLOGE("file transfer failed fail %{public}d", status); + } + return status; +} + +int32_t ObjectServiceImpl::BindAssetStore(const std::string &bundleName, const std::string &sessionId, + ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + return status; + } + status = ObjectStoreManager::GetInstance()->BindAsset(tokenId, bundleName, sessionId, asset, bindInfo); + if (status != OBJECT_SUCCESS) { + ZLOGE("bind asset fail %{public}d, bundleName:%{public}s, sessionId:%{public}s, assetName:%{public}s", status, + bundleName.c_str(), sessionId.c_str(), asset.name.c_str()); + } + return status; +} + int32_t ObjectServiceImpl::OnInitialize() { ZLOGI("Initialize"); @@ -198,6 +233,17 @@ int32_t ObjectServiceImpl::UnregisterDataChangeObserver(const std::string &bundl return OBJECT_SUCCESS; } +int32_t ObjectServiceImpl::DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) +{ + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + return status; + } + ObjectStoreManager::GetInstance()->DeleteSnapshot(bundleName, sessionId); + return OBJECT_SUCCESS; +} + int32_t ObjectServiceImpl::IsBundleNameEqualTokenId( const std::string &bundleName, const std::string &sessionId, const uint32_t &tokenId) { @@ -283,6 +329,28 @@ int32_t ObjectServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, con ObjectServiceImpl::ObjectServiceImpl() { + auto process = [](const Event& event) { + auto& evt = static_cast(event); + auto eventInfo = evt.GetBindInfo(); + StoreMetaData meta; + meta.storeId = eventInfo.storeName; + meta.bundleName = eventInfo.bundleName; + meta.user = std::to_string(eventInfo.user); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), + meta.GetStoreAlias().c_str()); + return; + } + auto store = AutoCache::GetInstance().GetStore(meta, {}); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + return; + } + auto bindAssets = ObjectStoreManager::GetInstance()->GetSnapShots(eventInfo.bundleName, eventInfo.storeName); + store->BindSnapshots(bindAssets); + }; + EventCenter::GetInstance().Subscribe(BindEvent::BIND_SNAPSHOT, process); } void ObjectServiceImpl::RegisterObjectServiceInfo() diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h index f06aab09..ae213fd8 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h @@ -38,6 +38,7 @@ public: int32_t RegisterDataObserver(const std::string &bundleName, const std::string &sessionId, sptr callback) override; int32_t UnregisterDataChangeObserver(const std::string &bundleName, const std::string &sessionId) override; + int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId) override; int32_t IsBundleNameEqualTokenId( const std::string &bundleName, const std::string &sessionId, const uint32_t &tokenId); void Clear(); @@ -47,7 +48,10 @@ public: int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnBind(const BindInfo &bindInfo) override; void DumpObjectServiceInfo(int fd, std::map> ¶ms); - + int32_t OnAssetChanged(const std::string &bundleName, const std::string &sessionId, + const std::string &deviceId, const ObjectStore::Asset &assetValue) override; + int32_t BindAssetStore(const std::string &bundleName, const std::string &sessionId, + ObjectStore::Asset &asset, ObjectStore::AssetBindInfo &bindInfo) override; private: using StaticActs = DistributedData::StaticActs; class ObjectStatic : public StaticActs { diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp index a97dd72d..eed34291 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.cpp @@ -19,7 +19,7 @@ #include -#include "itypes_util.h" +#include "common_type_util.h" #include "log_print.h" #include "utils/anonymous.h" @@ -50,6 +50,51 @@ int32_t ObjectServiceStub::ObjectStoreSaveOnRemote(MessageParcel &data, MessageP return 0; } +int32_t ObjectServiceStub::OnAssetChangedOnRemote(MessageParcel &data, MessageParcel &reply) +{ + std::string sessionId; + std::string bundleName; + std::string deviceId; + if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, deviceId)) { + ZLOGE("Unmarshal fail sessionId:%{public}s bundleName:%{public}s deviceId:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str(), + DistributedData::Anonymous::Change(deviceId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + ObjectStore::Asset assetValue; + if (!ITypesUtil::Unmarshalling(assetValue, data)) { + ZLOGE("Unmarshal assetValue fail, asset name: %{public}s", assetValue.name.c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t status = OnAssetChanged(bundleName, sessionId, deviceId, assetValue); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return status; +} + +int32_t ObjectServiceStub::ObjectStoreBindAssetOnRemote(MessageParcel &data, MessageParcel &reply) +{ + std::string sessionId; + std::string bundleName; + ObjectStore::Asset asset; + ObjectStore::AssetBindInfo bindInfo; + if (!ITypesUtil::Unmarshal(data, bundleName, sessionId, asset, bindInfo)) { + ZLOGE("Unmarshal sessionId:%{public}s bundleName:%{public}s assetName:%{public}s bindStore:%{public}s", + DistributedData::Anonymous::Change(sessionId).c_str(), bundleName.c_str(), + asset.name.c_str(), bindInfo.storeName.c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + int32_t status = BindAssetStore(bundleName, sessionId, asset, bindInfo); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + int32_t ObjectServiceStub::ObjectStoreRevokeSaveOnRemote(MessageParcel &data, MessageParcel &reply) { std::string sessionId; @@ -133,6 +178,23 @@ int32_t ObjectServiceStub::OnUnsubscribeRequest(MessageParcel &data, MessageParc return 0; } +int32_t ObjectServiceStub::OnDeleteSnapshot(MessageParcel &data, MessageParcel &reply) +{ + std::string sessionId; + std::string bundleName; + if (!ITypesUtil::Unmarshal(data, bundleName, sessionId)) { + 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 = DeleteSnapshot(bundleName, sessionId); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return 0; +} + bool ObjectServiceStub::CheckInterfaceToken(MessageParcel& data) { auto localDescriptor = IObjectService::GetDescriptor(); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h index 6acd6c75..8e71f952 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_stub.h @@ -33,7 +33,9 @@ private: int32_t ObjectStoreRetrieveOnRemote(MessageParcel &data, MessageParcel &reply); int32_t OnSubscribeRequest(MessageParcel &data, MessageParcel &reply); int32_t OnUnsubscribeRequest(MessageParcel &data, MessageParcel &reply); - + int32_t OnAssetChangedOnRemote(MessageParcel &data, MessageParcel &reply); + int32_t ObjectStoreBindAssetOnRemote(MessageParcel &data, MessageParcel &reply); + int32_t OnDeleteSnapshot(MessageParcel &data, MessageParcel &reply); using RequestHandle = int (ObjectServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(ObjectCode::OBJECTSTORE_SERVICE_CMD_MAX)] = { &ObjectServiceStub::ObjectStoreSaveOnRemote, @@ -41,6 +43,9 @@ private: &ObjectServiceStub::ObjectStoreRetrieveOnRemote, &ObjectServiceStub::OnSubscribeRequest, &ObjectServiceStub::OnUnsubscribeRequest, + &ObjectServiceStub::OnAssetChangedOnRemote, + &ObjectServiceStub::ObjectStoreBindAssetOnRemote, + &ObjectServiceStub::OnDeleteSnapshot, }; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/irdb_result_set.h b/datamgr_service/services/distributeddataservice/service/rdb/irdb_result_set.h index 5926784c..45d4a17b 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/irdb_result_set.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/irdb_result_set.h @@ -20,9 +20,8 @@ #include "remote_result_set.h" namespace OHOS::DistributedRdb { -class IRdbResultSet : public NativeRdb::RemoteResultSet, public IRemoteBroker { +class IRdbResultSet : public IRemoteBroker { public: - using ColumnType = NativeRdb::ColumnType; virtual ~IRdbResultSet() = default; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS::NativeRdb.IResultSet"); }; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp index 97785674..213c3d4a 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp @@ -22,9 +22,10 @@ #include "value_proxy.h" using namespace DistributedDB; +using ValueProxy = OHOS::DistributedData::ValueProxy; namespace OHOS::DistributedRdb { -RdbAssetLoader::RdbAssetLoader(std::shared_ptr cloudAssetLoader) - : assetLoader_(std::move(cloudAssetLoader)) +RdbAssetLoader::RdbAssetLoader(std::shared_ptr cloudAssetLoader, BindAssets* bindAssets) + : assetLoader_(std::move(cloudAssetLoader)), snapshots_(bindAssets) { } @@ -32,12 +33,14 @@ DBStatus RdbAssetLoader::Download(const std::string &tableName, const std::strin std::map &assets) { DistributedData::VBucket downLoadAssets = ValueProxy::Convert(assets); + std::set skipAssets; + PostEvent(skipAssets, downLoadAssets, DistributedData::AssetEvent::DOWNLOAD); DistributedDB::Type prefixTemp = prefix; auto error = assetLoader_->Download(tableName, gid, ValueProxy::Convert(std::move(prefixTemp)), downLoadAssets); - if (error == DistributedData::GeneralError::E_OK) { - assets = ValueProxy::Convert(std::move(downLoadAssets)); - } - return RdbCloud::ConvertStatus(static_cast(error)); + PostEvent(skipAssets, downLoadAssets, DistributedData::AssetEvent::DOWNLOAD_FINISHED); + assets = ValueProxy::Convert(std::move(downLoadAssets)); + return skipAssets.empty() ? RdbCloud::ConvertStatus(static_cast(error)) + : CLOUD_RECORD_EXIST_CONFLICT; } DBStatus RdbAssetLoader::RemoveLocalAssets(const std::vector &assets) @@ -46,4 +49,43 @@ DBStatus RdbAssetLoader::RemoveLocalAssets(const std::vector &assets) auto error = assetLoader_->RemoveLocalAssets("", "", {}, deleteAssets); return RdbCloud::ConvertStatus(static_cast(error)); } + +void RdbAssetLoader::PostEvent(std::set& skipAssets, + std::map& assets, DistributedData::AssetEvent eventId) +{ + for (auto& asset : assets) { + auto* downLoadAssets = Traits::get_if(&asset.second); + if (downLoadAssets == nullptr) { + return; + } + PostEvent(eventId, *downLoadAssets, skipAssets); + } +} + +void RdbAssetLoader::PostEvent(DistributedData::AssetEvent eventId, DistributedData::Assets& assets, + std::set& skipAssets) +{ + for (auto& downLoadAsset : assets) { + if (downLoadAsset.status == DistributedData::Asset::STATUS_DELETE) { + continue; + } + auto it = snapshots_->bindAssets->find(downLoadAsset.uri); + if (it == snapshots_->bindAssets->end()) { + continue; + } + auto snapshot = it->second; + if (eventId == DistributedData::DOWNLOAD) { + snapshot->Download(downLoadAsset); + if (snapshot->GetAssetStatus(downLoadAsset) == DistributedData::STATUS_WAIT_DOWNLOAD) { + skipAssets.insert(downLoadAsset.uri); + } + } else { + auto pos = skipAssets.find(downLoadAsset.uri); + if (pos != skipAssets.end()) { + continue; + } + snapshot->Downloaded(downLoadAsset); + } + } +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.h index a7ffb153..ba78c8c5 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H +#include "snapshot/snapshot.h" #include "cloud/asset_loader.h" #include "cloud/cloud_store_types.h" #include "cloud/iAssetLoader.h" @@ -27,7 +28,9 @@ public: using Type = DistributedDB::Type; using Asset = DistributedDB::Asset; using DBStatus = DistributedDB::DBStatus; - explicit RdbAssetLoader(std::shared_ptr cloudAssetLoader); + using BindAssets = DistributedData::BindAssets; + + explicit RdbAssetLoader(std::shared_ptr cloudAssetLoader, BindAssets* bindAssets); ~RdbAssetLoader() = default; @@ -38,6 +41,11 @@ public: private: std::shared_ptr assetLoader_; + BindAssets* snapshots_; + void PostEvent(std::set& skipAssets, std::map& assets, + DistributedData::AssetEvent eventId); + void PostEvent(DistributedData::AssetEvent eventId, DistributedData::Assets& assets, + std::set& skipAssets); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_ASSET_LOADER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp index ea9180e9..8209904c 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -26,16 +26,22 @@ namespace OHOS::DistributedRdb { using namespace DistributedDB; using namespace DistributedData; -RdbCloud::RdbCloud(std::shared_ptr cloudDB) - : cloudDB_(std::move(cloudDB)) +RdbCloud::RdbCloud(std::shared_ptr cloudDB, BindAssets* bindAssets) + : cloudDB_(std::move(cloudDB)), snapshots_(bindAssets) { } DBStatus RdbCloud::BatchInsert( const std::string &tableName, std::vector &&record, std::vector &extend) { - DistributedData::VBuckets extends = ValueProxy::Convert(std::move(extend)); - auto error = cloudDB_->BatchInsert(tableName, ValueProxy::Convert(std::move(record)), extends); + extend.resize(record.size()); + VBuckets extends = ValueProxy::Convert(std::move(extend)); + VBuckets records = ValueProxy::Convert(std::move(record)); + VBuckets temp = records; + std::set skipAssets; + PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD); + auto error = cloudDB_->BatchInsert(tableName, std::move(records), extends); + PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -43,8 +49,14 @@ DBStatus RdbCloud::BatchInsert( DBStatus RdbCloud::BatchUpdate( const std::string &tableName, std::vector &&record, std::vector &extend) { - DistributedData::VBuckets extends = ValueProxy::Convert(std::move(extend)); - auto error = cloudDB_->BatchUpdate(tableName, ValueProxy::Convert(std::move(record)), extends); + extend.resize(record.size()); + VBuckets extends = ValueProxy::Convert(std::move(extend)); + VBuckets records = ValueProxy::Convert(std::move(record)); + std::set skipAssets; + VBuckets temp = records; + PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD); + auto error = cloudDB_->BatchUpdate(tableName, std::move(records), extends); + PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -137,6 +149,8 @@ DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) return DBStatus::CLOUD_FULL_RECORDS; case GeneralError::E_NO_SPACE_FOR_ASSET: return DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT; + case GeneralError::E_RECORD_EXIST_CONFLICT: + return DBStatus::CLOUD_RECORD_EXIST_CONFLICT; default: ZLOGI("error:0x%{public}x", error); break; @@ -204,4 +218,61 @@ RdbCloud::QueryNodes RdbCloud::ConvertQuery(RdbCloud::DBQueryNodes&& nodes) } return queryNodes; } + +void RdbCloud::PostEvent(VBuckets& records, std::set& skipAssets, VBuckets& extend, + DistributedData::AssetEvent eventId) +{ + int32_t index = 0; + for (auto& record : records) { + DataBucket& ext = extend[index++]; + for (auto& [key, value] : record) { + PostEvent(value, ext, skipAssets, eventId); + } + } +} + +void RdbCloud::PostEvent(DistributedData::Value& value, DataBucket& extend, std::set& skipAssets, + DistributedData::AssetEvent eventId) +{ + if (value.index() != TYPE_INDEX && value.index() != TYPE_INDEX) { + return; + } + + if (value.index() == TYPE_INDEX) { + auto* asset = Traits::get_if(&value); + PostEventAsset(*asset, extend, skipAssets, eventId); + } + + if (value.index() == TYPE_INDEX) { + auto* assets = Traits::get_if(&value); + for (auto& asset : *assets) { + PostEventAsset(asset, extend, skipAssets, eventId); + } + } +} + +void RdbCloud::PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, std::set& skipAssets, + DistributedData::AssetEvent eventId) +{ + auto it = snapshots_->bindAssets->find(asset.uri); + if (it == snapshots_->bindAssets->end()) { + return; + } + + if (eventId == DistributedData::UPLOAD) { + it->second->Upload(asset); + if (it->second->GetAssetStatus(asset) == TransferStatus::STATUS_WAIT_UPLOAD) { + skipAssets.insert(asset.uri); + extend[SchemaMeta::ERROR_FIELD] = DBStatus::CLOUD_RECORD_EXIST_CONFLICT; + } + } + + if (eventId == DistributedData::UPLOAD_FINISHED) { + auto skip = skipAssets.find(asset.uri); + if (skip != skipAssets.end()) { + return; + } + it->second->Uploaded(asset); + } +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h index 121eb837..3960df08 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -19,6 +19,7 @@ #include "cloud/cloud_store_types.h" #include "cloud/icloud_db.h" #include "error/general_error.h" +#include "snapshot/snapshot.h" namespace OHOS::DistributedRdb { class RdbCloud : public DistributedDB::ICloudDb { @@ -26,8 +27,10 @@ public: using DBStatus = DistributedDB::DBStatus; using DBVBucket = DistributedDB::VBucket; using DBQueryNodes = std::vector; + using DataBucket = DistributedData::VBucket; + using BindAssets = DistributedData::BindAssets; - explicit RdbCloud(std::shared_ptr cloudDB); + explicit RdbCloud(std::shared_ptr cloudDB, BindAssets* bindAssets); virtual ~RdbCloud() = default; DBStatus BatchInsert(const std::string &tableName, std::vector &&record, std::vector &extend) override; @@ -50,6 +53,14 @@ private: static QueryNodes ConvertQuery(DBQueryNodes&& nodes); static constexpr int32_t TO_MS = 1000; // s > ms std::shared_ptr cloudDB_; + BindAssets* snapshots_; + + void PostEvent(DistributedData::VBuckets& records, std::set& skipAssets, + DistributedData::VBuckets& extend, DistributedData::AssetEvent eventId); + void PostEvent(DistributedData::Value& value, DataBucket& extend, std::set& skipAssets, + DistributedData::AssetEvent eventId); + void PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, std::set& skipAssets, + DistributedData::AssetEvent eventId); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp index e4bedeac..05d7d580 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp @@ -23,6 +23,7 @@ using Asset = DistributedDB::Asset; using Assets = DistributedDB::Assets; using DataAsset = NativeRdb::ValueObject::Asset; using DataAssets = NativeRdb::ValueObject::Assets; +using ValueProxy = DistributedData::ValueProxy; std::vector RdbCloudDataTranslate::AssetToBlob(const Asset &asset) { std::vector rawData; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index 47bb3963..50a94154 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -15,23 +15,25 @@ #define LOG_TAG "RdbGeneralStore" #include "rdb_general_store.h" #include "cache_cursor.h" -#include "cloud_service.h" #include "cloud/asset_loader.h" #include "cloud/cloud_db.h" #include "cloud/cloud_store_types.h" #include "cloud/schema_meta.h" +#include "cloud_service.h" #include "crypto_manager.h" +#include "device_manager_adapter.h" +#include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" #include "rdb_cursor.h" #include "rdb_helper.h" #include "rdb_query.h" +#include "rdb_result_set_impl.h" #include "relational_store_manager.h" +#include "snapshot/bind_event.h" #include "utils/anonymous.h" #include "value_proxy.h" -#include "device_manager_adapter.h" -#include "rdb_result_set_impl.h" namespace OHOS::DistributedRdb { using namespace DistributedData; using namespace DistributedDB; @@ -64,6 +66,12 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI } option.observer = &observer_; manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); + storeInfo_.tokenId = meta.tokenId; + storeInfo_.bundleName = meta.bundleName; + storeInfo_.storeName = meta.storeId; + storeInfo_.instanceId = meta.instanceId; + storeInfo_.user = std::stoi(meta.user); + if (delegate_ != nullptr && meta.isManualClean) { PragmaData data = static_cast(const_cast(static_cast(&meta.isManualClean))); @@ -84,6 +92,14 @@ RdbGeneralStore::~RdbGeneralStore() rdbLoader_ = nullptr; } +int32_t RdbGeneralStore::BindSnapshots(std::shared_ptr>> bindAssets) +{ + if (snapshots_.bindAssets == nullptr) { + snapshots_.bindAssets = bindAssets; + } + return GenErr::E_OK; +} + int32_t RdbGeneralStore::Bind(const Database &database, BindInfo bindInfo) { if (bindInfo.db_ == nullptr || bindInfo.loader_ == nullptr) { @@ -94,9 +110,19 @@ int32_t RdbGeneralStore::Bind(const Database &database, BindInfo bindInfo) return GeneralError::E_OK; } + BindEvent::BindEventInfo eventInfo; + eventInfo.tokenId = storeInfo_.tokenId; + eventInfo.bundleName = storeInfo_.bundleName; + eventInfo.storeName = storeInfo_.storeName; + eventInfo.user = storeInfo_.user; + eventInfo.instanceId = storeInfo_.instanceId; + + auto evt = std::make_unique(BindEvent::BIND_SNAPSHOT, std::move(eventInfo)); + EventCenter::GetInstance().PostEvent(std::move(evt)); bindInfo_ = std::move(bindInfo); - rdbCloud_ = std::make_shared(bindInfo_.db_); - rdbLoader_ = std::make_shared(bindInfo_.loader_); + rdbCloud_ = std::make_shared(bindInfo_.db_, &snapshots_); + rdbLoader_ = std::make_shared(bindInfo_.loader_, &snapshots_); + DBSchema schema; schema.tables.resize(database.tables.size()); for (size_t i = 0; i < database.tables.size(); i++) { @@ -209,6 +235,18 @@ std::shared_ptr RdbGeneralStore::Query(const std::string &table, GenQuer return nullptr; } +int32_t RdbGeneralStore::MergeMigratedData(const std::string& tableName, VBuckets&& values) +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database already closed! tables name:%{public}s", Anonymous::Change(tableName).c_str()); + return GeneralError::E_ERROR; + } + + auto status = delegate_->UpsertData(tableName, ValueProxy::Convert(std::move(values))); + return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; +} + int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &query, DetailAsync async, int32_t wait) { DistributedDB::Query dbQuery; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h index d1c9a695..ef8ad3aa 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -27,6 +27,7 @@ #include "relational_store_manager.h" #include "store/general_store.h" #include "store/general_value.h" +#include "snapshot/snapshot.h" namespace OHOS::DistributedRdb { class RdbGeneralStore : public DistributedData::GeneralStore { public: @@ -41,6 +42,8 @@ public: using GenErr = DistributedData::GeneralError; using RdbStore = OHOS::NativeRdb::RdbStore; using Reference = DistributedData::Reference; + using Snapshot = DistributedData::Snapshot; + using BindAssets = DistributedData::BindAssets; explicit RdbGeneralStore(const StoreMetaData &meta); ~RdbGeneralStore(); @@ -67,7 +70,8 @@ public: int32_t Close() override; int32_t AddRef() override; int32_t Release() override; - + int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; + int32_t MergeMigratedData(const std::string &tableName, VBuckets&& values) override; private: using RdbDelegate = DistributedDB::RelationalStoreDelegate; using RdbManager = DistributedDB::RelationalStoreManager; @@ -116,6 +120,9 @@ private: std::mutex mutex_; int32_t ref_ = 1; mutable std::shared_mutex rwMutex_; + + BindAssets snapshots_; + DistributedData::StoreInfo storeInfo_; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp index 269654c9..05ff5392 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp @@ -15,10 +15,11 @@ #define LOG_TAG "RdbResultSetImpl" -#include "rdb_result_set_impl.h" +#include #include "log_print.h" #include "store_types.h" #include "store/cursor.h" +#include "rdb_result_set_impl.h" using DistributedDB::DBStatus; using OHOS::NativeRdb::ColumnType; @@ -310,4 +311,29 @@ ColumnType RdbResultSetImpl::ConvertColumnType(int32_t columnType) const } return COLUMNTYPES[columnType]; } + +int RdbResultSetImpl::GetAsset(int32_t col, NativeRdb::ValueObject::Asset& value) +{ + return NativeRdb::E_NOT_SUPPORT; +} +int RdbResultSetImpl::GetAssets(int32_t col, NativeRdb::ValueObject::Assets& value) +{ + return NativeRdb::E_NOT_SUPPORT; +} +int RdbResultSetImpl::Get(int32_t col, NativeRdb::ValueObject& value) +{ + return NativeRdb::E_NOT_SUPPORT; +} +int RdbResultSetImpl::GetRow(NativeRdb::RowEntity& rowEntity) +{ + return NativeRdb::E_NOT_SUPPORT; +} +int RdbResultSetImpl::GetModifyTime(std::string& modifyTime) +{ + return NativeRdb::E_NOT_SUPPORT; +} +int RdbResultSetImpl::GetSize(int columnIndex, size_t& size) +{ + return NativeRdb::E_NOT_SUPPORT; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h index 58650063..8edfb4da 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h @@ -16,16 +16,19 @@ #ifndef DISTRIBUTED_RDB_RDB_RESULT_SET_IMPL_H #define DISTRIBUTED_RDB_RDB_RESULT_SET_IMPL_H +#include #include -#include "rdb_result_set_stub.h" +#include "result_set.h" #include "rdb_errno.h" #include "store/cursor.h" #include "value_proxy.h" #include "store/general_value.h" namespace OHOS::DistributedRdb { -class RdbResultSetImpl final : public RdbResultSetStub { +class RdbResultSetImpl final : public NativeRdb::ResultSet { public: + using ValueProxy = DistributedData::ValueProxy; + using ColumnType = NativeRdb::ColumnType; explicit RdbResultSetImpl(std::shared_ptr resultSet); ~RdbResultSetImpl() override {}; int GetAllColumnNames(std::vector &columnNames) override; @@ -53,6 +56,12 @@ public: int IsColumnNull(int columnIndex, bool &isNull) override; bool IsClosed() const override; int Close() override; + int GetAsset(int32_t col, NativeRdb::ValueObject::Asset& value) override; + int GetAssets(int32_t col, NativeRdb::ValueObject::Assets& value) override; + int Get(int32_t col, NativeRdb::ValueObject& value) override; + int GetRow(NativeRdb::RowEntity& rowEntity) override; + int GetModifyTime(std::string& modifyTime) override; + int GetSize(int columnIndex, size_t& size) override; private: template diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.cpp index d8b5e7ea..b46e3b83 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.cpp @@ -21,13 +21,16 @@ #include "rdb_result_set_stub.h" namespace OHOS::DistributedRdb { +RdbResultSetStub::RdbResultSetStub(std::shared_ptr resultSet) : resultSet_(std::move(resultSet)) +{ +} int RdbResultSetStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) { ZLOGD("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); - if (!CheckInterfaceToken(data)) { + if (!CheckInterfaceToken(data) || resultSet_ == nullptr) { return -1; } - if (code >= 0 && code < CMD_MAX) { + if (code >= 0 && code < Code::CMD_MAX) { return (this->*HANDLERS[code])(data, reply); } return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -47,17 +50,10 @@ bool RdbResultSetStub::CheckInterfaceToken(MessageParcel& data) int32_t RdbResultSetStub::OnGetAllColumnNames(MessageParcel &data, MessageParcel &reply) { std::vector columnNames; - int status = GetAllColumnNames(columnNames); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetAllColumnNames(columnNames); if (!ITypesUtil::Marshal(reply, status, columnNames)) { - ZLOGE("Write status or columnNames failed."); + ZLOGE("Write status or columnNames failed, status:%{public}d, columnNames size:%{public}zu.", status, + columnNames.size()); return -1; } return 0; @@ -66,17 +62,9 @@ int32_t RdbResultSetStub::OnGetAllColumnNames(MessageParcel &data, MessageParcel int32_t RdbResultSetStub::OnGetColumnCount(MessageParcel &data, MessageParcel &reply) { int columnCount = 0; - int status = GetColumnCount(columnCount); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetColumnCount(columnCount); if (!ITypesUtil::Marshal(reply, status, columnCount)) { - ZLOGE("Write status or columnCount failed."); + ZLOGE("Write status or columnCount failed, status:%{public}d, columnCount:%{public}d.", status, columnCount); return -1; } return 0; @@ -87,17 +75,10 @@ int32_t RdbResultSetStub::OnGetColumnType(MessageParcel &data, MessageParcel &re int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); NativeRdb::ColumnType columnType; - int status = GetColumnType(columnIndex, columnType); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetColumnType(columnIndex, columnType); if (!ITypesUtil::Marshal(reply, status, static_cast(columnType))) { - ZLOGE("Write status or columnType failed."); + ZLOGE("Write status or columnType failed, status:%{public}d, columnIndex:%{public}d, columnType:%{public}d.", + status, columnIndex, static_cast(columnType)); return -1; } return 0; @@ -108,17 +89,10 @@ int32_t RdbResultSetStub::OnGetColumnIndex(MessageParcel &data, MessageParcel &r std::string columnName; ITypesUtil::Unmarshal(data, columnName); int columnIndex; - int status = GetColumnIndex(columnName, columnIndex); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnName: %{public}s.", status, columnName.c_str()); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetColumnIndex(columnName, columnIndex); if (!ITypesUtil::Marshal(reply, status, columnIndex)) { - ZLOGE("Write status or columnIndex failed."); + ZLOGE("Write status or columnIndex failed, status:%{public}d, columnIndex:%{public}d, columnName:%{public}s.", + status, columnIndex, columnName.c_str()); return -1; } return 0; @@ -129,17 +103,10 @@ int32_t RdbResultSetStub::OnGetColumnName(MessageParcel &data, MessageParcel &re int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); std::string columnName; - int status = GetColumnName(columnIndex, columnName); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetColumnName(columnIndex, columnName); if (!ITypesUtil::Marshal(reply, status, columnName)) { - ZLOGE("Write status or columnName failed."); + ZLOGE("Write status or columnName failed, status:%{public}d, columnIndex:%{public}d, columnName:%{public}s.", + status, columnIndex, columnName.c_str()); return -1; } return 0; @@ -148,17 +115,9 @@ int32_t RdbResultSetStub::OnGetColumnName(MessageParcel &data, MessageParcel &re int32_t RdbResultSetStub::OnGetRowCount(MessageParcel &data, MessageParcel &reply) { int rowCount = 0; - int status = GetRowCount(rowCount); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetRowCount(rowCount); if (!ITypesUtil::Marshal(reply, status, rowCount)) { - ZLOGE("Write status or rowCount failed."); + ZLOGE("Write status or rowCount failed, status:%{public}d, rowCount:%{public}d.", status, rowCount); return -1; } return 0; @@ -167,17 +126,9 @@ int32_t RdbResultSetStub::OnGetRowCount(MessageParcel &data, MessageParcel &repl int32_t RdbResultSetStub::OnGetRowIndex(MessageParcel &data, MessageParcel &reply) { int rowIndex = 0; - int status = GetRowIndex(rowIndex); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetRowIndex(rowIndex); if (!ITypesUtil::Marshal(reply, status, rowIndex)) { - ZLOGE("Write status or rowIndex failed."); + ZLOGE("Write status or rowIndex failed, status:%{public}d, rowIndex:%{public}d.", status, rowIndex); return -1; } return 0; @@ -187,13 +138,9 @@ int32_t RdbResultSetStub::OnGoTo(MessageParcel &data, MessageParcel &reply) { int offSet; ITypesUtil::Unmarshal(data, offSet); - int status = GoTo(offSet); - if (status != 0) { - ZLOGE("failed, status: %{public}d offset: %{public}d.", status, offSet); - } - + int status = resultSet_->GoTo(offSet); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d, offSet:%{public}d.", status, offSet); return -1; } return 0; @@ -203,13 +150,9 @@ int32_t RdbResultSetStub::OnGoToRow(MessageParcel &data, MessageParcel &reply) { int position; ITypesUtil::Unmarshal(data, position); - int status = GoToRow(position); - if (status != 0) { - ZLOGE("failed, status: %{public}d position: %{public}d.", status, position); - } - + int status = resultSet_->GoToRow(position); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d, position:%{public}d.", status, position); return -1; } return 0; @@ -217,12 +160,9 @@ int32_t RdbResultSetStub::OnGoToRow(MessageParcel &data, MessageParcel &reply) int32_t RdbResultSetStub::OnGoToFirstRow(MessageParcel &data, MessageParcel &reply) { - int status = GoToFirstRow(); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - } + int status = resultSet_->GoToFirstRow(); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d.", status); return -1; } return 0; @@ -230,12 +170,9 @@ int32_t RdbResultSetStub::OnGoToFirstRow(MessageParcel &data, MessageParcel &rep int32_t RdbResultSetStub::OnGoToLastRow(MessageParcel &data, MessageParcel &reply) { - int status = GoToLastRow(); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - } + int status = resultSet_->GoToLastRow(); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d.", status); return -1; } return 0; @@ -243,12 +180,9 @@ int32_t RdbResultSetStub::OnGoToLastRow(MessageParcel &data, MessageParcel &repl int32_t RdbResultSetStub::OnGoToNextRow(MessageParcel &data, MessageParcel &reply) { - int status = GoToNextRow(); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - } + int status = resultSet_->GoToNextRow(); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d.", status); return -1; } return 0; @@ -256,12 +190,9 @@ int32_t RdbResultSetStub::OnGoToNextRow(MessageParcel &data, MessageParcel &repl int32_t RdbResultSetStub::OnGoToPreviousRow(MessageParcel &data, MessageParcel &reply) { - int status = GoToPreviousRow(); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - } + int status = resultSet_->GoToPreviousRow(); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d.", status); return -1; } return 0; @@ -270,17 +201,9 @@ int32_t RdbResultSetStub::OnGoToPreviousRow(MessageParcel &data, MessageParcel & int32_t RdbResultSetStub::OnIsEnded(MessageParcel &data, MessageParcel &reply) { bool isEnded = false; - int status = IsEnded(isEnded); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->IsEnded(isEnded); if (!ITypesUtil::Marshal(reply, status, isEnded)) { - ZLOGE("Write status or isEnded failed."); + ZLOGE("Write status or isEnded failed, status:%{public}d, isEnded:%{public}d.", status, isEnded); return -1; } return 0; @@ -289,17 +212,9 @@ int32_t RdbResultSetStub::OnIsEnded(MessageParcel &data, MessageParcel &reply) int32_t RdbResultSetStub::OnIsStarted(MessageParcel &data, MessageParcel &reply) { bool isStarted = false; - int status = IsStarted(isStarted); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->IsStarted(isStarted); if (!ITypesUtil::Marshal(reply, status, isStarted)) { - ZLOGE("Write status or isStarted failed."); + ZLOGE("Write status or isStarted failed, status:%{public}d, isStarted:%{public}d.", status, isStarted); return -1; } return 0; @@ -308,17 +223,9 @@ int32_t RdbResultSetStub::OnIsStarted(MessageParcel &data, MessageParcel &reply) int32_t RdbResultSetStub::OnIsAtFirstRow(MessageParcel &data, MessageParcel &reply) { bool isAtFirstRow = false; - int status = IsAtFirstRow(isAtFirstRow); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->IsAtFirstRow(isAtFirstRow); if (!ITypesUtil::Marshal(reply, status, isAtFirstRow)) { - ZLOGE("Write status or isAtFirstRow failed."); + ZLOGE("Write status or isAtFirstRow failed, status:%{public}d, isAtFirstRow:%{public}d", status, isAtFirstRow); return -1; } return 0; @@ -327,17 +234,9 @@ int32_t RdbResultSetStub::OnIsAtFirstRow(MessageParcel &data, MessageParcel &rep int32_t RdbResultSetStub::OnIsAtLastRow(MessageParcel &data, MessageParcel &reply) { bool isAtLastRow = false; - int status = IsAtLastRow(isAtLastRow); - if (status != 0) { - ZLOGE("failed, status: %{public}d", status); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->IsAtLastRow(isAtLastRow); if (!ITypesUtil::Marshal(reply, status, isAtLastRow)) { - ZLOGE("Write status or isAtLastRow failed."); + ZLOGE("Write status or isAtLastRow failed, status:%{public}d, isAtLastRow:%{public}d.", status, isAtLastRow); return -1; } return 0; @@ -348,17 +247,9 @@ int32_t RdbResultSetStub::OnGetBlob(MessageParcel &data, MessageParcel &reply) int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); std::vector blob; - int status = GetBlob(columnIndex, blob); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetBlob(columnIndex, blob); if (!ITypesUtil::Marshal(reply, status, blob)) { - ZLOGE("Write status or blob failed."); + ZLOGE("Write status or blob failed, status:%{public}d, columnIndex:%{public}d.", status, columnIndex); return -1; } return 0; @@ -369,17 +260,9 @@ int32_t RdbResultSetStub::OnGetString(MessageParcel &data, MessageParcel &reply) int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); std::string value; - int status = GetString(columnIndex, value); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetString(columnIndex, value); if (!ITypesUtil::Marshal(reply, status, value)) { - ZLOGE("Write status or string value failed."); + ZLOGE("Write status or string value failed, status:%{public}d, columnIndex:%{public}d.", status, columnIndex); return -1; } return 0; @@ -390,17 +273,9 @@ int32_t RdbResultSetStub::OnGetInt(MessageParcel &data, MessageParcel &reply) int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); int value; - int status = GetInt(columnIndex, value); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetInt(columnIndex, value); if (!ITypesUtil::Marshal(reply, status, value)) { - ZLOGE("Write status or int value failed."); + ZLOGE("Write status or int value failed, status:%{public}d, columnIndex:%{public}d", status, columnIndex); return -1; } return 0; @@ -411,17 +286,9 @@ int32_t RdbResultSetStub::OnGetLong(MessageParcel &data, MessageParcel &reply) int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); int64_t value; - int status = GetLong(columnIndex, value); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetLong(columnIndex, value); if (!ITypesUtil::Marshal(reply, status, value)) { - ZLOGE("Write status or long value failed."); + ZLOGE("Write status or long value failed, status:%{public}d, columnIndex:%{public}d", status, columnIndex); return -1; } return 0; @@ -432,17 +299,9 @@ int32_t RdbResultSetStub::OnGetDouble(MessageParcel &data, MessageParcel &reply) int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); double value; - int status = GetDouble(columnIndex, value); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->GetDouble(columnIndex, value); if (!ITypesUtil::Marshal(reply, status, value)) { - ZLOGE("Write status or double value failed."); + ZLOGE("Write status or double value failed, status:%{public}d, columnIndex:%{public}d", status, columnIndex); return -1; } return 0; @@ -453,17 +312,9 @@ int32_t RdbResultSetStub::OnIsColumnNull(MessageParcel &data, MessageParcel &rep int columnIndex; ITypesUtil::Unmarshal(data, columnIndex); bool isColumnNull; - int status = IsColumnNull(columnIndex, isColumnNull); - if (status != 0) { - ZLOGE("failed, status: %{public}d columnIndex: %{public}d.", status, columnIndex); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); - return -1; - } - return 0; - } + int status = resultSet_->IsColumnNull(columnIndex, isColumnNull); if (!ITypesUtil::Marshal(reply, status, isColumnNull)) { - ZLOGE("Write status or isColumnNull failed."); + ZLOGE("Write status or isColumnNull failed, status:%{public}d, columnIndex:%{public}d.", status, columnIndex); return -1; } return 0; @@ -471,9 +322,9 @@ int32_t RdbResultSetStub::OnIsColumnNull(MessageParcel &data, MessageParcel &rep int32_t RdbResultSetStub::OnIsClosed(MessageParcel &data, MessageParcel &reply) { - bool isClosed = IsClosed(); + bool isClosed = resultSet_->IsClosed(); if (!ITypesUtil::Marshal(reply, isClosed)) { - ZLOGE("Write isClosed failed."); + ZLOGE("Write isClosed failed, isClosed:%{public}d.", isClosed); return -1; } return 0; @@ -481,9 +332,9 @@ int32_t RdbResultSetStub::OnIsClosed(MessageParcel &data, MessageParcel &reply) int32_t RdbResultSetStub::OnClose(MessageParcel &data, MessageParcel &reply) { - int status = Close(); + int status = resultSet_->Close(); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Write status failed."); + ZLOGE("Write status failed, status:%{public}d.", status); return -1; } return 0; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.h index b3b95fe5..ef115be4 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_stub.h @@ -18,10 +18,13 @@ #include #include "irdb_result_set.h" +#include "result_set.h" namespace OHOS::DistributedRdb { class RdbResultSetStub : public IRemoteStub { public: + using Code = NativeRdb::RemoteResultSet::Code; + explicit RdbResultSetStub(std::shared_ptr resultSet); int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; private: @@ -53,33 +56,34 @@ private: static bool CheckInterfaceToken(MessageParcel &data); using RequestHandle = int (RdbResultSetStub::*)(MessageParcel &, MessageParcel &); - static constexpr RequestHandle HANDLERS[CMD_MAX] = { - [CMD_GET_ALL_COLUMN_NAMES] = &RdbResultSetStub::OnGetAllColumnNames, - [CMD_GET_COLUMN_COUNT] = &RdbResultSetStub::OnGetColumnCount, - [CMD_GET_COLUMN_TYPE] = &RdbResultSetStub::OnGetColumnType, - [CMD_GET_COLUMN_INDEX] = &RdbResultSetStub::OnGetColumnIndex, - [CMD_GET_COLUMN_NAME] = &RdbResultSetStub::OnGetColumnName, - [CMD_GET_ROW_COUNT] = &RdbResultSetStub::OnGetRowCount, - [CMD_GET_ROW_INDEX] = &RdbResultSetStub::OnGetRowIndex, - [CMD_GO_TO] = &RdbResultSetStub::OnGoTo, - [CMD_GO_TO_ROW] = &RdbResultSetStub::OnGoToRow, - [CMD_GO_TO_FIRST_ROW] = &RdbResultSetStub::OnGoToFirstRow, - [CMD_GO_TO_LAST_ROW] = &RdbResultSetStub::OnGoToLastRow, - [CMD_GO_TO_NEXT_ROW] = &RdbResultSetStub::OnGoToNextRow, - [CMD_GO_TO_PREV_ROW] = &RdbResultSetStub::OnGoToPreviousRow, - [CMD_IS_ENDED_ROW] = &RdbResultSetStub::OnIsEnded, - [CMD_IS_STARTED_ROW] = &RdbResultSetStub::OnIsStarted, - [CMD_IS_AT_FIRST_ROW] = &RdbResultSetStub::OnIsAtFirstRow, - [CMD_IS_AT_LAST_ROW] = &RdbResultSetStub::OnIsAtLastRow, - [CMD_GET_BLOB] = &RdbResultSetStub::OnGetBlob, - [CMD_GET_STRING] = &RdbResultSetStub::OnGetString, - [CMD_GET_INT] = &RdbResultSetStub::OnGetInt, - [CMD_GET_LONG] = &RdbResultSetStub::OnGetLong, - [CMD_GET_DOUBLE] = &RdbResultSetStub::OnGetDouble, - [CMD_IS_COLUMN_NULL] = &RdbResultSetStub::OnIsColumnNull, - [CMD_IS_CLOSED] = &RdbResultSetStub::OnIsClosed, - [CMD_CLOSE] = &RdbResultSetStub::OnClose + static constexpr RequestHandle HANDLERS[Code::CMD_MAX] = { + [Code::CMD_GET_ALL_COLUMN_NAMES] = &RdbResultSetStub::OnGetAllColumnNames, + [Code::CMD_GET_COLUMN_COUNT] = &RdbResultSetStub::OnGetColumnCount, + [Code::CMD_GET_COLUMN_TYPE] = &RdbResultSetStub::OnGetColumnType, + [Code::CMD_GET_COLUMN_INDEX] = &RdbResultSetStub::OnGetColumnIndex, + [Code::CMD_GET_COLUMN_NAME] = &RdbResultSetStub::OnGetColumnName, + [Code::CMD_GET_ROW_COUNT] = &RdbResultSetStub::OnGetRowCount, + [Code::CMD_GET_ROW_INDEX] = &RdbResultSetStub::OnGetRowIndex, + [Code::CMD_GO_TO] = &RdbResultSetStub::OnGoTo, + [Code::CMD_GO_TO_ROW] = &RdbResultSetStub::OnGoToRow, + [Code::CMD_GO_TO_FIRST_ROW] = &RdbResultSetStub::OnGoToFirstRow, + [Code::CMD_GO_TO_LAST_ROW] = &RdbResultSetStub::OnGoToLastRow, + [Code::CMD_GO_TO_NEXT_ROW] = &RdbResultSetStub::OnGoToNextRow, + [Code::CMD_GO_TO_PREV_ROW] = &RdbResultSetStub::OnGoToPreviousRow, + [Code::CMD_IS_ENDED_ROW] = &RdbResultSetStub::OnIsEnded, + [Code::CMD_IS_STARTED_ROW] = &RdbResultSetStub::OnIsStarted, + [Code::CMD_IS_AT_FIRST_ROW] = &RdbResultSetStub::OnIsAtFirstRow, + [Code::CMD_IS_AT_LAST_ROW] = &RdbResultSetStub::OnIsAtLastRow, + [Code::CMD_GET_BLOB] = &RdbResultSetStub::OnGetBlob, + [Code::CMD_GET_STRING] = &RdbResultSetStub::OnGetString, + [Code::CMD_GET_INT] = &RdbResultSetStub::OnGetInt, + [Code::CMD_GET_LONG] = &RdbResultSetStub::OnGetLong, + [Code::CMD_GET_DOUBLE] = &RdbResultSetStub::OnGetDouble, + [Code::CMD_IS_COLUMN_NULL] = &RdbResultSetStub::OnIsColumnNull, + [Code::CMD_IS_CLOSED] = &RdbResultSetStub::OnIsClosed, + [Code::CMD_CLOSE] = &RdbResultSetStub::OnClose }; + std::shared_ptr resultSet_; }; } // namespace OHOS::DistributedRdb #endif // DISTRIBUTED_RDB_RDB_RESULT_SET_STUB_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index a86ff247..57253451 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -17,6 +17,7 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "checker/checker_manager.h" +#include "abs_rdb_predicates.h" #include "cloud/change_event.h" #include "cloud/cloud_share_event.h" #include "cloud/make_query_event.h" @@ -33,7 +34,9 @@ #include "metadata/store_meta_data.h" #include "rdb_watcher.h" #include "rdb_notifier_proxy.h" +#include "rdb_query.h" #include "store/general_store.h" +#include "tokenid_kit.h" #include "types_export.h" #include "utils/anonymous.h" #include "utils/constant.h" @@ -73,8 +76,7 @@ RdbServiceImpl::Factory::Factory() return store; }); staticActs_ = std::make_shared(); - FeatureSystem::GetInstance().RegisterStaticActs(RdbServiceImpl::SERVICE_NAME, - staticActs_); + FeatureSystem::GetInstance().RegisterStaticActs(RdbServiceImpl::SERVICE_NAME, staticActs_); } RdbServiceImpl::Factory::~Factory() @@ -124,6 +126,11 @@ RdbServiceImpl::RdbServiceImpl() rdbQuery->SetColumns(evt.GetColumns()); callback(rdbQuery); }); + auto compensateSyncProcess = [this] (const Event &event) { + auto &evt = static_cast(event); + DoCompensateSync(evt); + }; + EventCenter::GetInstance().Subscribe(BindEvent::COMPENSATE_SYNC, compensateSyncProcess); } int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) @@ -217,7 +224,7 @@ std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptr notifier) { if (!CheckAccess(param.bundleName_, "")) { - ZLOGE("permission error"); + ZLOGE("bundleName:%{public}s. Permission error", param.bundleName_.c_str()); return RDB_ERROR; } if (notifier == nullptr) { @@ -326,38 +333,31 @@ RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const }; } -int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) +std::pair> RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, + const std::string& device, const std::string& sql, const std::vector& selectionArgs) { if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); - return RDB_ERROR; + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return { RDB_ERROR, nullptr }; } auto store = GetStore(param); if (store == nullptr) { ZLOGE("store is null"); - return RDB_ERROR; + return { RDB_ERROR, nullptr }; } RdbQuery rdbQuery; rdbQuery.MakeRemoteQuery(device, sql, ValueProxy::Convert(selectionArgs)); auto cursor = store->Query("", rdbQuery); - if (cursor == nullptr) { - ZLOGE("Query failed, cursor is null"); - return RDB_ERROR; - } - resultSet = new (std::nothrow) RdbResultSetImpl(cursor); - if (resultSet == nullptr) { - ZLOGE("new resultSet failed"); - return RDB_ERROR; - } - return RDB_OK; + return { RDB_OK, std::make_shared(cursor) }; } int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } if (option.mode < DistributedData::GeneralStore::CLOUD_END && @@ -404,6 +404,31 @@ int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option false); } +void RdbServiceImpl::DoCompensateSync(const BindEvent& event) +{ + auto bindInfo = event.GetBindInfo(); + CloudEvent::StoreInfo storeInfo; + storeInfo.bundleName = bindInfo.bundleName; + storeInfo.tokenId = bindInfo.tokenId; + storeInfo.user = bindInfo.user; + storeInfo.storeName = bindInfo.storeName; + OHOS::NativeRdb::AbsRdbPredicates predicates(bindInfo.tableName); + for (auto& [key, value] : bindInfo.primaryKey) { + predicates.In(key, std::vector({ ValueProxy::Convert(std::move(value)) })); + } + auto memo = predicates.GetDistributedPredicates(); + std::shared_ptr query = nullptr; + if (!memo.tables_.empty()) { + query = std::make_shared(); + query->MakeCloudQuery(memo); + } + + auto mixMode = GeneralStore::MixMode(TIME_FIRST, GeneralStore::AUTO_SYNC_MODE); + auto info = ChangeEvent::EventInfo(mixMode, 0, false, query, nullptr); + auto evt = std::make_unique(std::move(storeInfo), std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} + void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService::Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { @@ -563,11 +588,13 @@ int32_t RdbServiceImpl::Delete(const RdbSyncerParam ¶m) return RDB_OK; } -std::pair> RdbServiceImpl::QuerySharingResource( +std::pair> RdbServiceImpl::QuerySharingResource( const RdbSyncerParam& param, const PredicatesMemo& predicates, const std::vector& columns) { - if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); + if (!CheckAccess(param.bundleName_, param.storeName_) || + !TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return { RDB_ERROR, {} }; } if (predicates.tables_.empty()) { @@ -583,16 +610,16 @@ std::pair> RdbServiceImpl::QuerySh storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId); storeInfo.storeName = RemoveSuffix(param.storeName_); - auto [status, cursor] = PreShare(storeInfo, rdbQuery); + auto [status, cursor] = AllocResource(storeInfo, rdbQuery); if (cursor == nullptr) { ZLOGE("cursor is null, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return { RDB_ERROR, {} }; } - return { RDB_OK, HandleCursor(cursor) }; + return { RDB_OK, std::make_shared(cursor) }; } -std::pair> RdbServiceImpl::PreShare(CloudEvent::StoreInfo& storeInfo, +std::pair> RdbServiceImpl::AllocResource(CloudEvent::StoreInfo& storeInfo, std::shared_ptr rdbQuery) { std::pair> result; @@ -608,7 +635,8 @@ std::pair> RdbServiceImpl::PreShare(CloudEvent: int32_t RdbServiceImpl::GetSchema(const RdbSyncerParam ¶m) { if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } StoreMetaData storeMeta; @@ -739,28 +767,6 @@ Details RdbServiceImpl::HandleGenDetails(const GenDetails &details) return dbDetails; } -std::vector RdbServiceImpl::HandleCursor(std::shared_ptr cursor) -{ - std::vector valueBuckets; - if (cursor == nullptr) { - return valueBuckets; - } - int32_t count = cursor->GetCount(); - valueBuckets.reserve(count); - auto err = cursor->MoveToFirst(); - while (err == E_OK && count > 0) { - DistributedData::VBucket entry; - err = cursor->GetEntry(entry); - if (err != E_OK) { - break; - } - valueBuckets.emplace_back(ValueProxy::Convert(std::move(entry))); - err = cursor->MoveToNext(); - count--; - } - return valueBuckets; -} - bool RdbServiceImpl::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) { if (!metaData.isEncrypt) { @@ -925,6 +931,11 @@ RdbServiceImpl::~RdbServiceImpl() int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData) { + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } CloudEvent::StoreInfo storeInfo; storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); storeInfo.bundleName = param.bundleName_; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h index 07b0f3eb..5c21e6f7 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -34,6 +34,7 @@ #include "store_observer.h" #include "visibility.h" #include "store/general_value.h" +#include "snapshot/bind_event.h" namespace OHOS::DistributedRdb { class API_EXPORT RdbServiceImpl : public RdbServiceStub { @@ -54,8 +55,8 @@ public: int32_t SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, const std::vector &references, int32_t type = DISTRIBUTED_DEVICE) override; - int32_t RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) override; + std::pair> RemoteQuery(const RdbSyncerParam& param, const std::string& device, + const std::string& sql, const std::vector& selectionArgs) override; int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) override; @@ -79,7 +80,7 @@ public: int32_t Delete(const RdbSyncerParam ¶m) override; - std::pair> QuerySharingResource(const RdbSyncerParam& param, + std::pair> QuerySharingResource(const RdbSyncerParam& param, const PredicatesMemo& predicates, const std::vector& columns) override; int32_t OnBind(const BindInfo &bindInfo) override; @@ -136,6 +137,8 @@ private: void DoCloudSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); + void DoCompensateSync(const DistributedData::BindEvent& event); + int DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); @@ -157,13 +160,11 @@ private: int32_t Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old); - std::pair> PreShare( + std::pair> AllocResource( StoreInfo& storeInfo, std::shared_ptr rdbQuery); static Details HandleGenDetails(const DistributedData::GenDetails &details); - static std::vector HandleCursor(std::shared_ptr cursor); - static std::string TransferStringToHex(const std::string& origStr); static std::string RemoveSuffix(const std::string& name); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 92511ac6..4e1f084f 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -20,6 +20,7 @@ #include "log_print.h" #include "itypes_util.h" #include "utils/anonymous.h" +#include "rdb_result_set_stub.h" namespace OHOS::DistributedRdb { using Anonymous = DistributedData::Anonymous; @@ -197,9 +198,9 @@ int32_t RdbServiceStub::OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel return IPC_STUB_INVALID_DATA_ERR; } - sptr resultSet; - auto status = RemoteQuery(param, device, sql, selectionArgs, resultSet); - if (!ITypesUtil::Marshal(reply, status, resultSet)) { + auto [status, resultSet] = RemoteQuery(param, device, sql, selectionArgs); + sptr object = new RdbResultSetStub(resultSet); + if (!ITypesUtil::Marshal(reply, status, object->AsObject())) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; } @@ -293,7 +294,8 @@ int32_t RdbServiceStub::OnRemoteQuerySharingResource(MessageParcel& data, Messag } auto [status, resultSet] = QuerySharingResource(param, predicates, columns); - if (!ITypesUtil::Marshal(reply, status, resultSet)) { + sptr object = new RdbResultSetStub(resultSet); + if (!ITypesUtil::Marshal(reply, status, object->AsObject())) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; } diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index 75fea5f5..49a0ac6b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -27,8 +27,12 @@ config("module_private_config") { "../crypto/include/", "../directory/include/", "../matrix/include/", + "../common/", "../rdb/", + "../object/", "../../framework/include/", + "${dataobject_path}/interfaces/innerkits", + "${dataobject_path}/frameworks/innerkitsimpl/include", ] defines = [ @@ -71,12 +75,14 @@ ohos_unittest("CloudDataTest") { ohos_unittest("ValueProxyTest") { module_out_path = module_output_path sources = [ - "../rdb/value_proxy.cpp", + "../common/value_proxy.cpp", "value_proxy_test.cpp", ] - include_dirs = - [ "../../../../../relational_store/interfaces/inner_api/rdb/include" ] + include_dirs = [ + "../../../../../relational_store/interfaces/inner_api/rdb/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", + ] configs = [ ":module_private_config" ] @@ -206,9 +212,9 @@ ohos_unittest("DeviceMatrixTest") { ohos_unittest("RdbResultSetImplTest") { module_out_path = module_output_path sources = [ + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", - "${data_service_path}/service/rdb/value_proxy.cpp", "mock/cursor_mock.cpp", "rdb_result_set_impl_test.cpp", ] @@ -217,6 +223,7 @@ ohos_unittest("RdbResultSetImplTest") { "${data_service_path}/service/rdb", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/rdb/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", ] configs = [ ":module_private_config" ] @@ -273,15 +280,48 @@ ohos_unittest("CacheCursorTest") { ] } +ohos_unittest("ObjectAssetMachineTest") { + module_out_path = module_output_path + sources = [ + "../object/object_asset_machine.cpp", + "object_asset_machine_test.cpp", + ] + + include_dirs = [ "${dataobject_path}/interfaces/innerkits" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${kv_store_distributeddb_path}:distributeddb", + "${relational_store_inner_api_path}:native_rdb_static", + "../../adapter:distributeddata_adapter", + "../../framework:distributeddatasvcfwk", + "../../service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { testonly = true deps = [] + if (datamgr_service_config) { + deps += [ ":ConfigFactoryTest" ] + } + deps += [ ":CloudDataTest", - ":ConfigFactoryTest", ":CryptoManagerTest", ":DeviceMatrixTest", ":DirectoryManagerTest", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn index 09c1094d..32dcbf68 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn @@ -26,6 +26,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/backup/include", "${data_service_path}/service/bootstrap/include", "${data_service_path}/service/cloud", + "${data_service_path}/service/common", "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", "${data_service_path}/service/kvdb", @@ -44,6 +45,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${dataobject_path}/frameworks/innerkitsimpl/include", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/rdb/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", "//third_party/json/single_include", ] @@ -67,6 +69,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/cloud/cloud_types_util.cpp", "${data_service_path}/service/cloud/cloud_value_util.cpp", "${data_service_path}/service/cloud/sync_manager.cpp", + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", @@ -89,7 +92,6 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/rdb/rdb_service_impl.cpp", "${data_service_path}/service/rdb/rdb_service_stub.cpp", "${data_service_path}/service/rdb/rdb_watcher.cpp", - "${data_service_path}/service/rdb/value_proxy.cpp", "cloudservicestub_fuzzer.cpp", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn index ea9521bd..a85fde35 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -26,6 +26,7 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/common/include", "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", "${data_service_path}/service/kvdb", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn index 0e81f7c6..5f0153aa 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -25,6 +25,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", "${data_service_path}/service/bootstrap/include", + "${data_service_path}/service/common", "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", "${data_service_path}/service/object", @@ -37,6 +38,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${kv_store_distributeddb_path}/interfaces/include/", "${kv_store_distributeddb_path}/interfaces/include/relational", "${dataobject_path}/frameworks/innerkitsimpl/include", + "${dataobject_path}/interfaces/innerkits", "//third_party/json/single_include", ] @@ -53,6 +55,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { sources = [ "${data_service_path}/service/backup/src/backup_manager.cpp", "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", @@ -62,11 +65,15 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/config/src/model/network_config.cpp", "${data_service_path}/service/config/src/model/protocol_config.cpp", "${data_service_path}/service/crypto/src/crypto_manager.cpp", + "${data_service_path}/service/object/object_asset_loader.cpp", + "${data_service_path}/service/object/object_asset_machine.cpp", "${data_service_path}/service/object/object_callback_proxy.cpp", "${data_service_path}/service/object/object_data_listener.cpp", "${data_service_path}/service/object/object_manager.cpp", "${data_service_path}/service/object/object_service_impl.cpp", "${data_service_path}/service/object/object_service_stub.cpp", + "${data_service_path}/service/object/object_snapshot.cpp", + "${data_service_path}/service/object/object_types_utils.cpp", "objectservicestub_fuzzer.cpp", ] @@ -87,11 +94,13 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "c_utils:utils", "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", + "dfs_service:cloudsync_asset_kit_inner", "hilog:libhilog", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", + "relational_store:common_type", ] } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn index 42e6bc8e..ba197743 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn @@ -24,6 +24,7 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "${data_service_path}/app/src", "${data_service_path}/framework/include", "${data_service_path}/service/rdb", + "${data_service_path}/service/common", "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", @@ -34,6 +35,7 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "${kv_store_distributeddb_path}/interfaces/include/relational", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/rdb/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", "//third_party/json/single_include", ] @@ -48,9 +50,9 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { ] sources = [ + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", - "${data_service_path}/service/rdb/value_proxy.cpp", "rdbresultsetstub_fuzzer.cpp", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp index 288cb24d..5d6cdf74 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp @@ -17,8 +17,10 @@ #include #include +#include #include "rdb_result_set_impl.h" +#include "rdb_result_set_stub.h" #include "message_parcel.h" #include "store/cursor.h" #include "securec.h" @@ -40,7 +42,8 @@ bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) MessageParcel reply; MessageOption option; std::shared_ptr dbResultSet; - std::shared_ptr rdbResultSetStub = std::make_shared(dbResultSet); + auto result = std::make_shared(dbResultSet); + std::shared_ptr rdbResultSetStub = std::make_shared(result); rdbResultSetStub->OnRemoteRequest(code, request, reply, option); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn index 64b489cd..a6080530 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -26,6 +26,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/service/backup/include", "${data_service_path}/service/bootstrap/include", "${data_service_path}/service/cloud", + "${data_service_path}/service/common", "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", "${data_service_path}/service/data_share", @@ -45,6 +46,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${dataobject_path}/frameworks/innerkitsimpl/include", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/rdb/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", "//third_party/json/single_include", ] @@ -63,6 +65,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/app/src/checker/system_checker.cpp", "${data_service_path}/service/backup/src/backup_manager.cpp", "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", @@ -85,7 +88,6 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/service/rdb/rdb_service_impl.cpp", "${data_service_path}/service/rdb/rdb_service_stub.cpp", "${data_service_path}/service/rdb/rdb_watcher.cpp", - "${data_service_path}/service/rdb/value_proxy.cpp", "rdbservicestub_fuzzer.cpp", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp index 93437c0f..088c4254 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp @@ -313,9 +313,7 @@ DBStatus DBStoreMock::UpdateKey(const UpdateKeyCallback &callback) DBStatus DBStoreMock::Reset() { - entries_.Clear(); - localEntries_.Clear(); - return OK; + return USER_CHANGED; } } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp index 9f2752c2..76956b18 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp @@ -21,17 +21,17 @@ StoreMetaData GeneralStoreMock::GetStoreMetaData() { return StoreMetaData(); } -int32_t GeneralStoreMock::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) +int32_t GeneralStoreMock::Clean(const std::vector& devices, int32_t mode, const std::string& tableName) { return 0; } -GeneralStoreMock::GeneralStoreMock(const StoreMetaData &meta) {} +GeneralStoreMock::GeneralStoreMock(const StoreMetaData& meta) {} GeneralStoreMock::~GeneralStoreMock() {} bool GeneralStoreMock::IsValid() { return true; } -int32_t GeneralStoreMock::Bind(const Database &database, GeneralStore::BindInfo bindInfo) +int32_t GeneralStoreMock::Bind(const Database& database, GeneralStore::BindInfo bindInfo) { return 0; } @@ -39,42 +39,42 @@ bool GeneralStoreMock::IsBound() { return false; } -int32_t GeneralStoreMock::Execute(const std::string &table, const std::string &sql) +int32_t GeneralStoreMock::Execute(const std::string& table, const std::string& sql) { return 0; } -int32_t GeneralStoreMock::SetDistributedTables(const std::vector &tables, int type, - const std::vector &references) +int32_t GeneralStoreMock::SetDistributedTables(const std::vector& tables, int type, + const std::vector& references) { return 0; } -int32_t GeneralStoreMock::BatchInsert(const std::string &table, VBuckets &&values) +int32_t GeneralStoreMock::BatchInsert(const std::string& table, VBuckets&& values) { return 0; } -int32_t GeneralStoreMock::BatchUpdate(const std::string &table, const std::string &sql, VBuckets &&values) +int32_t GeneralStoreMock::BatchUpdate(const std::string& table, const std::string& sql, VBuckets&& values) { return 0; } -int32_t GeneralStoreMock::Delete(const std::string &table, const std::string &sql, Values &&args) +int32_t GeneralStoreMock::Delete(const std::string& table, const std::string& sql, Values&& args) { return 0; } -std::shared_ptr GeneralStoreMock::Query(const std::string &table, const std::string &sql, Values &&args) +std::shared_ptr GeneralStoreMock::Query(const std::string& table, const std::string& sql, Values&& args) { return std::shared_ptr(); } -std::shared_ptr GeneralStoreMock::Query(const std::string &table, GenQuery &query) +std::shared_ptr GeneralStoreMock::Query(const std::string& table, GenQuery& query) { return std::shared_ptr(); } -int32_t GeneralStoreMock::Sync(const GeneralStore::Devices &devices, int32_t mode, GenQuery &query, +int32_t GeneralStoreMock::Sync(const GeneralStore::Devices& devices, int32_t mode, GenQuery& query, GeneralStore::DetailAsync async, int32_t wait) { return 0; } -int32_t GeneralStoreMock::Watch(int32_t origin, Watcher &watcher) +int32_t GeneralStoreMock::Watch(int32_t origin, Watcher& watcher) { if (origin != Watcher::Origin::ORIGIN_ALL || watcher_ != nullptr) { return GeneralError::E_INVALID_ARGS; @@ -84,7 +84,7 @@ int32_t GeneralStoreMock::Watch(int32_t origin, Watcher &watcher) return GeneralError::E_OK; } -int32_t GeneralStoreMock::Unwatch(int32_t origin, Watcher &watcher) +int32_t GeneralStoreMock::Unwatch(int32_t origin, Watcher& watcher) { if (origin != Watcher::Origin::ORIGIN_ALL || watcher_ != &watcher) { return GeneralError::E_INVALID_ARGS; @@ -109,8 +109,8 @@ int32_t GeneralStoreMock::Release() return 0; } -int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin &origin, const GeneralWatcher::PRIFields &primaries, - GeneralWatcher::ChangeInfo &&changeInfo) +int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin& origin, const GeneralWatcher::PRIFields& primaries, + GeneralWatcher::ChangeInfo&& changeInfo) { if (watcher_ != nullptr) { watcher_->OnChange(origin, primaries, std::move(changeInfo)); @@ -135,6 +135,14 @@ std::shared_ptr GeneralStoreMock::PreSharing(GenQuery& query) { return std::shared_ptr(); } +int32_t GeneralStoreMock::BindSnapshots(std::shared_ptr>> bindAssets) +{ + return 0; +} +int32_t GeneralStoreMock::MergeMigratedData(const std::string& tableName, VBuckets&& values) +{ + return 0; +} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h index dea94f99..a051a811 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h @@ -57,6 +57,9 @@ public: int32_t AddRef() override; int32_t Release() override; + int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; + + int32_t MergeMigratedData(const std::string &tableName, VBuckets&& values) override; int32_t OnChange(const GeneralWatcher::Origin &origin, const GeneralWatcher::PRIFields &primaries, GeneralWatcher::ChangeInfo &&changeInfo); diff --git a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp index 66767e32..dba39e9d 100644 --- a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp @@ -19,7 +19,7 @@ #include "value_proxy.h" namespace Test { using namespace testing::ext; -using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; class ValueProxyTest : public testing::Test { }; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 369acd91..22005052 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -528,6 +528,25 @@ int32_t UdmfServiceImpl::UdmfStatic::OnAppInstall(const std::string &bundleName, { ZLOGD("Bundle: %{public}s installed.", bundleName.c_str()); auto status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); + if (status != E_OK) { + ZLOGE("Install Utd failed, bundleName: %{public}s, status: %{public}d", bundleName.c_str(), status); + } + return status; +} + +int32_t UdmfServiceImpl::UdmfStatic::OnAppUpdate(const std::string &bundleName, int32_t user, + int32_t index) +{ + ZLOGD("Bundle: %{public}s Update.", bundleName.c_str()); + auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); + if (status != E_OK) { + ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); + return status; + } + status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); + if (status != E_OK) { + ZLOGE("Install utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); + } return status; } @@ -536,6 +555,9 @@ int32_t UdmfServiceImpl::UdmfStatic::OnAppUninstall(const std::string &bundleNam { ZLOGD("Bundle: %{public}s uninstalled.", bundleName.c_str()); auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); + if (status != E_OK) { + ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status); + } return status; } } // namespace UDMF diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h index 3326f3a5..aac010bc 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -61,6 +61,7 @@ private: public: ~UdmfStatic() override {}; int32_t OnAppInstall(const std::string &bundleName, int32_t user, int32_t index) override; + int32_t OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index) override; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) override; }; class Factory { diff --git a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp index 918c8097..2e08c4e4 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.cpp @@ -67,42 +67,28 @@ int32_t CustomUtdInstaller::InstallUtd(const std::string &bundleName, int32_t us std::vector customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(path); std::vector presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes(); std::vector modules = GetHapModules(bundleName, user); + bool isSucc = true; for (std::string module : modules) { auto utdTypes = GetModuleCustomUtdTypes(bundleName, module, user); + if (utdTypes.first.empty() && utdTypes.second.empty()) { + ZLOGW("Module custom utd types is empty."); + continue; + } if (!UtdCfgsChecker::GetInstance().CheckTypeDescriptors(utdTypes, presetTypes, customTyepCfgs, bundleName)) { ZLOGE("Parse json failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(), bundleName.c_str()); + isSucc = false; continue; } - // Update customTyepCfgs used for subsequent persistence of type definitions. - for (TypeDescriptorCfg &declarationType : utdTypes.first) { - for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) { - if (iter->typeId == declarationType.typeId) { - declarationType.installerBundles = iter->installerBundles; - iter = customTyepCfgs.erase(iter); - } else { - iter ++; - } - } - declarationType.installerBundles.emplace(bundleName); - declarationType.ownerBundle = bundleName; - customTyepCfgs.push_back(declarationType); - } - for (TypeDescriptorCfg &referenceType : utdTypes.second) { - bool found = false; - for (auto &typeCfg : customTyepCfgs) { - if (typeCfg.typeId == referenceType.typeId) { - typeCfg.installerBundles.emplace(bundleName); - found = true; - break; - } - } - if (!found) { - referenceType.installerBundles.emplace(bundleName); - customTyepCfgs.push_back(referenceType); - } + if (SaveCustomUtds(utdTypes, customTyepCfgs, bundleName, path) != E_OK) { + ZLOGE("Install save custom utds failed, moduleName: %{public}s, bundleName: %{public}s.", module.c_str(), + bundleName.c_str()); + isSucc = false; + continue; } - CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path); + } + if (!isSucc) { + return E_ERROR; } return E_OK; } @@ -143,7 +129,10 @@ int32_t CustomUtdInstaller::UninstallUtd(const std::string &bundleName, int32_t customIter++; } } - CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path); + if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) { + ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str()); + return E_ERROR; + } return E_OK; } @@ -158,16 +147,20 @@ std::vector CustomUtdInstaller::GetHapModules(const std::string &bu return bundleInfo.hapModuleNames; } -std::pair, std::vector> CustomUtdInstaller::GetModuleCustomUtdTypes( - const std::string &bundleName, const std::string &moduleName, int32_t user) +UtdCfgsChecker::CustomUtdCfgs CustomUtdInstaller::GetModuleCustomUtdTypes(const std::string &bundleName, + const std::string &utdJson, int32_t user) { auto bundlemgr = GetBundleManager(); std::string jsonStr; - std::pair, std::vector> typeCfgs; - auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, moduleName, jsonStr, + UtdCfgsChecker::CustomUtdCfgs typeCfgs; + auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, utdJson, jsonStr, user); if (status != NO_ERROR) { - ZLOGE("get local bundle info failed, jsonStr is %{public}s.", jsonStr.c_str()); + ZLOGE("get json profile failed, bundleName: %{public}s.", bundleName.c_str()); + return typeCfgs; + } + if (jsonStr.empty()) { + ZLOGE("JsonStr is empty, bundleName: %{public}s.", bundleName.c_str()); return typeCfgs; } std::vector declarationType; @@ -181,5 +174,42 @@ std::pair, std::vector> Custom } return typeCfgs; } + +int32_t CustomUtdInstaller::SaveCustomUtds(const UtdCfgsChecker::CustomUtdCfgs &utdTypes, std::vector customTyepCfgs, + const std::string &bundleName, const std::string &path) +{ + for (TypeDescriptorCfg declarationType : utdTypes.first) { + for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) { + if (iter->typeId == declarationType.typeId) { + declarationType.installerBundles = iter->installerBundles; + iter = customTyepCfgs.erase(iter); + } else { + iter ++; + } + } + declarationType.installerBundles.emplace(bundleName); + declarationType.ownerBundle = bundleName; + customTyepCfgs.push_back(declarationType); + } + for (TypeDescriptorCfg referenceType : utdTypes.second) { + bool found = false; + for (auto &typeCfg : customTyepCfgs) { + if (typeCfg.typeId == referenceType.typeId) { + typeCfg.installerBundles.emplace(bundleName); + found = true; + break; + } + } + if (!found) { + referenceType.installerBundles.emplace(bundleName); + customTyepCfgs.push_back(referenceType); + } + } + if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, path) != E_OK) { + ZLOGE("Save type cfgs failed, bundleName: %{public}s.", bundleName.c_str()); + return E_ERROR; + } + return E_OK; } } +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h index 40a5c3bd..1db59987 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/utd/custom_utd_installer.h @@ -39,8 +39,9 @@ private: CustomUtdInstaller &operator=(const CustomUtdInstaller &obj) = delete; sptr GetBundleManager(); std::vector GetHapModules(const std::string &bundleName, int32_t user); - std::pair, std::vector> GetModuleCustomUtdTypes( - const std::string &bundleName, const std::string &moduleName, int32_t user); + UtdCfgsChecker::CustomUtdCfgs GetModuleCustomUtdTypes(const std::string &bundleName, const std::string &moduleName, int32_t user); + int32_t SaveCustomUtds(const UtdCfgsChecker::CustomUtdCfgs &utdTypes, std::vector customTyepCfgs, + const std::string &bundleName, const std::string &path); }; } // namespace UDMF } // namespace OHOS diff --git a/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts b/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts index 89461f72..406d0451 100644 --- a/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts +++ b/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback } from './@ohos.base'; import ExtensionContext from './application/ExtensionContext'; import Want from './@ohos.app.ability.Want'; diff --git a/interface_sdk/api/@ohos.data.DataShareResultSet.d.ts b/interface_sdk/api/@ohos.data.DataShareResultSet.d.ts index 77093809..16fab0e1 100644 --- a/interface_sdk/api/@ohos.data.DataShareResultSet.d.ts +++ b/interface_sdk/api/@ohos.data.DataShareResultSet.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + /** * Indicates the {@code DataType}. *

{@code DataType} is obtained based on the value. diff --git a/interface_sdk/api/@ohos.data.ValuesBucket.d.ts b/interface_sdk/api/@ohos.data.ValuesBucket.d.ts index e296eb05..dd4b6e73 100644 --- a/interface_sdk/api/@ohos.data.ValuesBucket.d.ts +++ b/interface_sdk/api/@ohos.data.ValuesBucket.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + /** * Indicates possible value types * diff --git a/interface_sdk/api/@ohos.data.cloudData.d.ts b/interface_sdk/api/@ohos.data.cloudData.d.ts index 46ae94b9..d7ecba33 100644 --- a/interface_sdk/api/@ohos.data.cloudData.d.ts +++ b/interface_sdk/api/@ohos.data.cloudData.d.ts @@ -13,7 +13,13 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback } from './@ohos.base'; +import type relationalStore from './@ohos.data.relationalStore'; declare namespace cloudData { /** @@ -220,38 +226,24 @@ declare namespace cloudData { static changeAppCloudSwitch(accountId: string, bundleName: string, status: boolean): Promise; /** - * notifies changes of the cloud records - * - * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. - * @param { string } bundleName - Indicates the name of application. - * @param { AsyncCallback } callback - the callback of notifyDataChange. - * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. - * @throws { BusinessError } 401 - Parameter error. - * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 10 - */ - static notifyDataChange(accountId: string, bundleName: string, callback: AsyncCallback): void; - - /** - * notifies changes of the cloud records + * Notifies changes of the cloud records. * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. - * @param { string } bundleName - Indicates the name of application. - * @returns { Promise } the promise returned by the function. - * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. + * @param { ExtraData } extInfo - Indicates the extra data for + * notification {@link ExtraData}. + * @param { number } [userId] - Indicates the user ID. + * @returns { Promise } Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server + * @syscap SystemCapability.DistributedDataManager.CloudSync.Config * @systemapi - * @since 10 + * @since 11 */ - static notifyDataChange(accountId: string, bundleName: string): Promise; + static notifyDataChange(extInfo: ExtraData, userId?: number): Promise; /** * Notifies changes of the cloud records. @@ -295,24 +287,38 @@ declare namespace cloudData { static notifyDataChange(extInfo: ExtraData, userId: number, callback: AsyncCallback): void; /** - * Notifies changes of the cloud records. + * notifies changes of the cloud records * * @permission ohos.permission.CLOUDDATA_CONFIG - * @param { ExtraData } extInfo - Indicates the extra data for - * notification {@link ExtraData}. - * @param { number } [userId] - Indicates the user ID. - * @returns { Promise } Promise used to return the result. - * @throws { BusinessError } 201 - Permission verification failed, which - * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { string } bundleName - Indicates the name of application. + * @returns { Promise } the promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. * @throws { BusinessError } 801 - Capability not supported. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Config + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi - * @since 11 + * @since 10 */ - static notifyDataChange(extInfo: ExtraData, userId?: number): Promise; + static notifyDataChange(accountId: string, bundleName: string): Promise; + + /** + * notifies changes of the cloud records + * + * @permission ohos.permission.CLOUDDATA_CONFIG + * @param { string } accountId - Indicates the account ID. The account ID is required by hashing cloud account. + * @param { string } bundleName - Indicates the name of application. + * @param { AsyncCallback } callback - the callback of notifyDataChange. + * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server + * @systemapi + * @since 10 + */ + static notifyDataChange(accountId: string, bundleName: string, callback: AsyncCallback): void; /** * deletes cloud information from local data. @@ -352,6 +358,793 @@ declare namespace cloudData { */ static clear(accountId: string, appActions: { [bundleName: string]: ClearAction }): Promise; } + + /** + * Provides methods to implement cloud sharing. + * + * @namespace sharing + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @since 11 + */ + export namespace sharing { + /** + * Enumerates the roles. + * + * @enum { number } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + enum Role { + /** + * ROLE_INVITER: means inviter of cloud sharing. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + ROLE_INVITER = 0, + + /** + * ROLE_INVITEE: means invitee of cloud sharing. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + ROLE_INVITEE = 1, + } + + /** + * Enumerates the states of sharing invitation. + * + * @enum { number } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + enum State { + /** + * STATE_UNKNOWN: Unknown state. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + STATE_UNKNOWN = 0, + + /** + * STATE_ACCEPTED: Accept the sharing invitation. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + STATE_ACCEPTED = 1, + + /** + * STATE_REJECTED: Reject the sharing invitation. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + STATE_REJECTED = 2, + + /** + * STATE_SUSPENDED: Suspend the sharing process. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + STATE_SUSPENDED = 3, + } + + /** + * Enumerates the error code of sharing invitation. + * + * @enum { number } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + enum SharingCode { + /** + * SUCCESS: means sharing success. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + SUCCESS = 0, + + /** + * REPEATED_REQUEST: means the user has been invited. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + REPEATED_REQUEST = 1, + + /** + * NOT_INVITER: means the participant is not inviter. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + NOT_INVITER = 2, + + /** + * NOT_INVITER_OR_INVITEE: means the participant is not inviter or invitee. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + NOT_INVITER_OR_INVITEE = 3, + + /** + * OVER_QUOTA: means the number of sharing times today of current user has reached maximum. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + OVER_QUOTA = 4, + + /** + * TOO_MANY_PARTICIPANTS: means the number of participants reaches the maximum. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + TOO_MANY_PARTICIPANTS = 5, + + /** + * INVALID_ARGS: means invalid arguments. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + INVALID_ARGS = 6, + + /** + * NETWORK_ERROR: means the network is unavailable. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + NETWORK_ERROR = 7, + + /** + * CLOUD_DISABLED: means cloud is disabled. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + CLOUD_DISABLED = 8, + + /** + * SERVER_ERROR: means invoke cloud space failed. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + SERVER_ERROR = 9, + + /** + * INNER_ERROR: means an unknown error has occurred. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + INNER_ERROR = 10, + + /** + * INVALID_INVITATION: means the invitation has expired or does not exist. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + INVALID_INVITATION = 11, + + /** + * RATE_LIMIT: means the data transfer is rate-limited. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + RATE_LIMIT = 12, + + /** + * CUSTOM_ERROR: means error codes that exceed this enumerated value are custom error codes. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + CUSTOM_ERROR = 1000, + } + + /** + * Result interface. + * + * @interface Result + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + interface Result { + /** + * Error code. + * + * @type { number } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + code: number; + + /** + * Error code description. + * + * @type { ?string } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + description?: string; + + /** + * The result value. + * + * @type { ?T } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + value?: T; + } + + /** + * Privilege for the shared data. + * + * @interface Privilege + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + interface Privilege { + /** + * Whether the participants can write the shared data. The value true + * means the participants can write the shared data; the value false + * means the opposite. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + writable?: boolean; + + /** + * Whether the participants can read the shared data. The value true + * means the participants can read the shared data; the value false + * means the opposite. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + readable?: boolean; + + /** + * Whether the participants can create data. The value true + * means the participants can create data; the value false + * means the opposite. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + creatable?: boolean; + + /** + * Whether the participants can delete the shared data. The value true + * means the participants can delete the shared data; the value false + * means the opposite. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + deletable?: boolean; + + /** + * Whether the participants can share the data. The value true + * means the participants can share the data; the value false + * means the opposite. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + shareable?: boolean; + } + + /** + * Participants in cloud sharing. + * + * @interface Participant + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + interface Participant { + /** + * Identity of participant. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + identity: string; + + /** + * Role of the participant, which can be inviter or invitee. + * + * @type { ?Role } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + role?: Role; + + /** + * State of the sharing invitation. + * + * @type { ?State } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + state?: State; + + /** + * Permissions for the shared data. + * + * @type { ?Privilege } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + privilege?: Privilege; + + /** + * Attach information. + * + * @type { ?string } + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + attachInfo?: string; + } + + /** + * Allocates shared resources based on conditions, + * and shares data with the specified privilege to participants. + * + * @param { string } storeId - Indicates relational store name. + * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. + * @param { Array } participants - Participants to share. + * @param { Array } [columns] - Columns to be shared. + * @returns { Promise } - Promise used to return {@link relationalStore.ResultSet}. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function allocResourceAndShare( + storeId: string, + predicates: relationalStore.RdbPredicates, + participants: Array, + columns?: Array + ): Promise; + + /** + * Allocates shared resources based on conditions, + * and shares data with the specified privilege to participants. + * + * @param { string } storeId - Indicates relational store name. + * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. + * @param { Array } participants - Participants to share. + * @param { AsyncCallback } callback - Indicates the + * callback invoked to return the {@link relationalStore.ResultSet}. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function allocResourceAndShare( + storeId: string, + predicates: relationalStore.RdbPredicates, + participants: Array, + callback: AsyncCallback + ): void; + + /** + * Allocates shared resources based on conditions, + * and shares data with the specified privilege to participants. + * + * @param { string } storeId - Indicates relational store name. + * @param { relationalStore.RdbPredicates } predicates - See {@link relationalStore.RdbPredicates}. + * @param { Array } participants - Participants to share. + * @param { Array } columns - Columns to be shared. + * @param { AsyncCallback } callback - Indicates the + * callback invoked to return the {@link relationalStore.ResultSet}. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function allocResourceAndShare( + storeId: string, + predicates: relationalStore.RdbPredicates, + participants: Array, + columns: Array, + callback: AsyncCallback + ): void; + + /** + * Shares data with the specified privilege to participants. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * involved in the data sharing. + * @param { AsyncCallback>>> } callback - Indicates the + * callback invoked to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function share( + sharingResource: string, + participants: Array, + callback: AsyncCallback>>> + ): void; + + /** + * Shares data with the specified privilege to participants. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * involved in the data sharing. + * @returns { Promise>>> } - Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function share( + sharingResource: string, + participants: Array + ): Promise>>>; + + /** + * UnShares data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * involved. + * @param { AsyncCallback>>> } callback - Indicates the callback invoked + * to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function unshare( + sharingResource: string, + participants: Array, + callback: AsyncCallback>>> + ): void; + + /** + * UnShares data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * involved. + * @returns { Promise>>> } - Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function unshare( + sharingResource: string, + participants: Array + ): Promise>>>; + + /** + * Exit sharing. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { AsyncCallback> } callback - The callback of exit. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function exit(sharingResource: string, callback: AsyncCallback>): void; + + /** + * Exit sharing. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @returns { Promise> } - The promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function exit(sharingResource: string): Promise>; + + /** + * Changes the permissions for the shared data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * whose permissions are to be changed. + * @param { AsyncCallback>>> } callback - Indicates the + * callback invoked to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function changePrivilege( + sharingResource: string, + participants: Array, + callback: AsyncCallback>>> + ): void; + + /** + * Changes the permissions for the shared data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participants + * whose permissions are to be changed. + * @returns { Promise>>> } - Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function changePrivilege( + sharingResource: string, + participants: Array + ): Promise>>>; + + /** + * Queries the participants based on the specified shared data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { AsyncCallback>> } callback - Indicates the + * callback invoked to return the participants obtained. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function queryParticipants(sharingResource: string, callback: AsyncCallback>>): void; + + /** + * Queries the participants based on the specified shared data. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @returns { Promise>> } - Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function queryParticipants(sharingResource: string): Promise>>; + + /** + * Queries the participants based on the specified invitation code. + * + * @param { string } invitationCode - Indicates the invitation code. + * @param { AsyncCallback>> } callback - Indicates the + * callback invoked to return the participants obtained. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function queryParticipantsByInvitation( + invitationCode: string, + callback: AsyncCallback>> + ): void; + + /** + * Queries the participants based on the specified invitation code. + * + * @param { string } invitationCode - Indicates the invitation code. + * @returns { Promise>> } - Promise used to return the result. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function queryParticipantsByInvitation(invitationCode: string): Promise>>; + + /** + * Confirms the invitation of cloud sharing. + * + * @param { string } invitationCode - Indicates the invitation code. + * @param { State } state - Indicates the state of invitation. + * @param { AsyncCallback> } callback - Indicates the callback + * invoked to return the sharing resource. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function confirmInvitation(invitationCode: string, state: State, callback: AsyncCallback>): void; + + /** + * Confirms the invitation of cloud sharing. + * + * @param { string } invitationCode - Indicates the invitation code. + * @param { State } state - Indicates the state of invitation. + * @returns { Promise> } - Promise used to return the sharing resource. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function confirmInvitation(invitationCode: string, state: State): Promise>; + + /** + * Changes confirmation of shared record. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { State } state - Indicates the state of invitation. + * @param { AsyncCallback> } callback - Indicates the callback. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function changeConfirmation(sharingResource: string, state: State, callback: AsyncCallback>): void; + + /** + * Changes confirmation of shared record. + * + * @param { string } sharingResource - Indicates the sharing resource. + * @param { State } state - Indicates the state of invitation. + * @returns { Promise> } - The promise returned by the function. + * @throws { BusinessError } 201 - Permission verification failed, which + * is usually returned by VerifyAccessToken. + * @throws { BusinessError } 202 - Permission verification failed, which is + * returned when the system API is not called by a system application. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + function changeConfirmation(sharingResource: string, state: State): Promise>; + } } export default cloudData; diff --git a/interface_sdk/api/@ohos.data.cloudExtension.d.ts b/interface_sdk/api/@ohos.data.cloudExtension.d.ts index 203f6fbf..e4ed23b0 100644 --- a/interface_sdk/api/@ohos.data.cloudExtension.d.ts +++ b/interface_sdk/api/@ohos.data.cloudExtension.d.ts @@ -13,10 +13,8 @@ * limitations under the License. */ -import type relationalStore from './@ohos.data.relationalStore'; import type rpc from './@ohos.rpc'; -import cloudData from "./@ohos.data.cloudData"; -import Result = cloudData.Sharing.Result; +import type cloudData from './@ohos.data.cloudData'; /** * Provides interfaces to implement extended cloud capabilities. @@ -27,736 +25,49 @@ import Result = cloudData.Sharing.Result; */ declare namespace cloudExtension { /** - * Defines valuesBucket, see {@link relationalStore.ValuesBucket}. + * Defines the result. * + * @interface Result * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 */ - type ValuesBucket = relationalStore.ValuesBucket; - - /** - * Defines cloud information. - * - * @interface CloudInfo - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface CloudInfo { - /** - * Cloud information. For details, see {@link ServiceInfo}. - * - * @type { ServiceInfo } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - cloudInfo: ServiceInfo; - - /** - * Defines brief application information. - * - * @type { object } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - apps: { [bundleName: string]: AppBriefInfo }; - } - - /** - * Defines cloud service information. - * - * @interface ServiceInfo - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface ServiceInfo { - /** - * Whether cloud is enabled. The value true means cloud is enabled; - * the value false means the opposite. - * - * @type { boolean } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - enableCloud: boolean; - - /** - * ID of the cloud account generated by using SHA-256. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - id: string; - - /** - * Total space (in KB) of the account on the server. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - totalSpace: number; - - /** - * Available space (in KB) of the account on the server. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - remainingSpace: number; - - /** - * Current user of the device. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - user: number; - } - - /** - * Defines the brief application information. - * - * @interface AppBriefInfo - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface AppBriefInfo { - /** - * ID of the application. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - appId: string; - - /** - * Bundle name. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - bundleName: string; - - /** - * Whether cloud is enabled for the application. - * The value true means the cloud is enabled; the false means - * the opposite. - * - * @type { boolean } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - cloudSwitch: boolean; - - /** - * Application instance ID. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - instanceId: number; - } - - /** - * Enumerates the field types. - * - * @enum { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export enum FieldType { - /** - * NULL. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - NULL = 0, - - /** - * Number. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - NUMBER, - - /** - * Real. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - REAL, - - /** - * Text. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - TEXT, - - /** - * Boolean. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - BOOL, - - /** - * BLOB. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - BLOB, - - /** - * Asset. For details, see {@link relationalStore.Asset}. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - ASSET, - - /** - * Assets. For details, see {@link relationalStore.Assets}. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - ASSETS - } - - /** - * Defines the fields. - * - * @interface Field - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface Field { - /** - * Alias of the field on the server. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - alias: string; - - /** - * Column name. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - colName: string; - - /** - * Type of the field. For details, see {@link FieldType}. - * - * @type { FieldType } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - type: FieldType; - - /** - * Whether the current column holds the primary key. - * - * @type { boolean } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - primary: boolean; - - /** - * Whether the current column is nullable. - * - * @type { boolean } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - nullable: boolean; - } - - /** - * Defines a table. - * - * @interface Table - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface Table { - /** - * Alias of the table on the server. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - alias: string; - - /** - * Name of the table. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - name: string; - - /** - * Fields in the table. For details, see {@link Field}. - * - * @type { Field[] } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - fields: Field[]; - } - - /** - * Defines a database. - * - * @interface Database - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface Database { - /** - * Name of the database. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - name: string; - - /** - * Alias of the database on the server. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - alias: string; - - /** - * Tables in the database. For details, see {@link Table}. - * - * @type { Table[] } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - tables: Table[]; - } - - /** - * Defines the application schema. - * - * @interface AppSchema - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface AppSchema { - /** - * Bundle name of the application. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - bundleName: string; - - /** - * Schema version. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - version: number; - - /** - * Databases {@link Database} of the application. - * - * @type { Array } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - databases: Array; - } - - /** - * Defines the data in the cloud. - * - * @interface CloudData - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface CloudData { - /** - * Next cursor for query. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - nextCursor: string; - - /** - * Whether the server has more data to query {@link CloudDB.query()}. - * - * @type { boolean } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - hasMore: boolean; - - /** - * Array of data queried, including the data values and extension - * values {@link ExtensionValue}. - * - * @type { Array } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - values: Array; - } - - /** - * Defines the subscription information. - * - * @interface SubscribeInfo - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface SubscribeInfo { - /** - * Subscription expiration time, in milliseconds. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - expirationTime: number; - - /** - * Data to be observed. - * - * @type { object } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - subscribe: { [bundleName: string]: Array }; - } - - /** - * Defines the subscription ID. - * - * @interface SubscribeId - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface SubscribeId { - /** - * Alias of the database on the server. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - databaseAlias: string; - - /** - * Subscription ID generated by {@link CloudService.subscribe()}. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - id: string; - } - - /** - * Enumerates the operations that can be performed on the database. - * - * @enum { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export enum Flag { - /** - * Insert data. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - INSERT, - - /** - * Update data. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - UPDATE, - - /** - * Delete data. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - DELETE - } - - /** - * Defines the extension values. - * - * @interface ExtensionValue - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface ExtensionValue { - /** - * ID generated by {@link CloudDB.insert()}. - * An ID is generated for each row when data is first inserted to the cloud. - * The ID must be unique for each table. - * - * @type { string } - * @readonly - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - readonly id: string; - - /** - * Time when the row data was created. - * - * @type { number } - * @readonly - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - readonly createTime: number; - - /** - * Time when the row data was last modified. - * - * @type { number } - * @readonly - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - readonly modifyTime: number; - - /** - * Database operation. - * - * @type { Flag } - * @readonly - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - readonly operation: Flag; - } - - /** - * Defines the lock information. - * - * @interface LockInfo - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface LockInfo { - /** - * Duration for which the cloud database is locked, in seconds. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - interval: number; - - /** - * Session ID for locking the cloud database. - * - * @type { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - sessionId: number; - } - - /** - * Enumerates the error codes. - * - * @enum { number } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export enum ErrorCode { - /** - * Successful. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - SUCCESS, - - /** - * Unknown error. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - UNKNOWN_ERROR, - + export interface Result { /** - * Network error. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - NETWORK_ERROR, - - /** - * Cloud is disabled. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - CLOUD_DISABLED, - - /** - * The cloud database is locked by others. + * Error code. * + * @type { number } * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 */ - LOCKED_BY_OTHERS, + code: number; /** - * The number of records exceeds the limit. + * Error code description. * + * @type { ?string } * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 */ - RECORD_LIMIT_EXCEEDED, + description?: string; /** - * The cloud has no space for the asset. + * Result value. * + * @type { ?T } * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 */ - NO_SPACE_FOR_ASSET + value?: T; } - /** - * Defines participant. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @since 11 - */ - type Participant = cloudData.Sharing.Participant; - - /** - * Defines participantStatus. - * - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @since 11 - */ - type ParticipantStatus = cloudData.Sharing.Status; - /** * Creates a share service stub with the specified instance. * - * @param { ShareService } instance - Indicates the ShareService instance. + * @param { ShareCenter } instance - Indicates the ShareCenter instance. * @returns { Promise } Returns remote object. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi @@ -775,321 +86,6 @@ declare namespace cloudExtension { */ function createCloudServiceStub(instance: CloudService): Promise; - /** - * Creates a cloud database stub with the specified instance. - * - * @param { CloudDB } instance - Indicates the CloudDB instance. - * @returns { Promise } Returns the remote object. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - function createCloudDBStub(instance: CloudDB): Promise; - - /** - * Creates an asset loader stub with the specified instance. - * - * @param { AssetLoader } instance - Indicates the AssetLoader instance. - * @returns { Promise } Returns remote object. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - function createAssetLoaderStub(instance: AssetLoader): Promise; - - /** - * Provides interfaces for implementing CloudService. - * - * @interface CloudService - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface CloudService { - /** - * Obtains the service information. - * - * @returns { Promise } Returns the service information obtained. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - getServiceInfo(): Promise; - - /** - * Obtains the brief application information. - * - * @returns { Promise<{ [bundleName: string]: AppBriefInfo }> } - * Returns the key-value pairs corresponding to bundle and - * AppBriefInfo. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - getAppBriefInfo(): Promise<{ [bundleName: string]: AppBriefInfo }>; - - /** - * Obtains the application schema information. - * - * @param { string } bundleName - Indicates the bundle name of the application. - * @returns { Promise> } Returns AppSchema. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - getAppSchema(bundleName: string): Promise>; - - /** - * Subscribes to data changes in the cloud. - * When the cloud server data is changed, the server notifies the device of - * the data change. - * - * @param { object } subInfo - Indicates - * the data to be subscribed to, that is, the key-value pairs corresponding - * to an array of bundle names and databases. - * @param { number } expirationTime - Indicates the subscription expiration - * time. - * @returns { Promise> } Returns SubscribeInfo. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - subscribe( - subInfo: { [bundleName: string]: Array }, - expirationTime: number - ): Promise>; - - /** - * Unsubscribes from the data changes in the cloud. - * - * @param { object } unsubscribeInfo - Indicates - * the data to be unsubscribe from, that is, the key-value pairs - * corresponding to an array of bundle names and databases. - * @returns { Promise } Returns unsubscribeInfo result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - unsubscribe(unsubscribeInfo: { [bundleName: string]: Array }): Promise; - - /** - * Connects to a database. - * - * @param { string } bundleName - Indicates the bundle name of the application. - * @param { Database } database - Indicates the database to connect. - * @returns { Promise } Returns connectDB RemoteObject. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - connectDB(bundleName: string, database: Database): Promise; - - /** - * Connects to an assetLoader. - * - * @param { string } bundleName - Indicates the bundle name of the application. - * @param { Database } database - Indicates the database of bundle. - * @returns { Promise } Returns connectAssetLoader RemoteObject. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - connectAssetLoader(bundleName: string, database: Database): Promise; - - /** - * Connects to a share center. - * - * @param { number } userId - Indicates the user ID. - * @param { string } bundleName - Indicates the bundle name. - * @returns { Promise } Returns connectAssetLoader RemoteObject. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - connectShareCenter(userId: number, bundleName: string): Promise; - } - - /** - * Provides interfaces for the operations on the cloud database. - * - * @interface CloudDB - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface CloudDB { - /** - * Generates the IDs of the rows of data to be inserted to the cloud. - * The IDs must be unique for each table. - * - * @param { number } count - Indicates the number of IDs to generate. - * @returns { Promise> } Returns the IDs generated. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - generateId(count: number): Promise>; - - /** - * Inserts data to the cloud. - * - * @param { string } table - Indicates the table name. - * @param { ValuesBucket[] } values - Indicates the data to insert. - * @param { ValuesBucket[] } extValues - Indicates the extension - * values {@link ExtensionValue}. - * @returns { Promise> } Returns the insert result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - insert(table: string, values: ValuesBucket[], extValues: ValuesBucket[]): Promise>; - - /** - * Updates data in the cloud. - * - * @param { string } table - Indicates the table name. - * @param { ValuesBucket[] } values - Indicates the new data. - * @param { ValuesBucket[] } extValues - Indicates the extension - * values {@link ExtensionValue}. - * @returns { Promise> } Returns the update result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - update(table: string, values: ValuesBucket[], extValues: ValuesBucket[]): Promise>; - - /** - * Deletes data. - * - * @param { string } table - Indicates the table name. - * @param { ValuesBucket[] } extValues - Indicates the extension - * values {@link ExtensionValue}. - * @returns { Promise> } Returns the delete result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - delete(table: string, extValues: ValuesBucket[]): Promise>; - - /** - * Queries data. - * - * @param { string } table - Indicates the table name. - * @param { string[] } fields - Indicates the columns to query. - * @param { number } queryCount - Indicates the number of data records - * to query. - * @param { string } queryCursor - Indicates the cursor. - * @returns { Promise> } Returns the query result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - query(table: string, fields: string[], queryCount: number, queryCursor: string): Promise>; - - /** - * Locks the cloud database. - * The cloud database will be unlocked when the lock interval has expired. - * When the cloud database is locked, other devices cannot synchronize data - * with the cloud. - * - * @returns { Promise> } Returns the locked information. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - lock(): Promise>; - - /** - * Uses the heartbeat to extend the lock interval if it is not enough. - * - * @param { number } sessionId - Indicates the session ID of the heartbeat. - * @returns { Promise> } Returns the time. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - heartbeat(sessionId: number): Promise>; - - /** - * Unlocks the cloud database. - * - * @param { number } sessionId - Indicates the session ID. - * @returns { Promise> } Returns the unlock result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - unlock(sessionId: number): Promise>; - } - - /** - * Provides interface for managing cloud assets. - * - * @interface CloudAsset - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface CloudAsset extends relationalStore.Asset { - /** - * Asset ID. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - assetId: string; - - /** - * Asset hash value. - * - * @type { string } - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - hash: string; - } - - /** - * Provides interfaces for implementing the asset loader. - * - * @interface AssetLoader - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - export interface AssetLoader { - - /** - * Downloads assets. - * - * @param { string } table - Indicates the name of the table. - * @param { string } gid - Indicates the GID. - * @param { string } prefix - Indicates the prefix information. - * @param { CloudAsset[] } assets - Indicates the assets to download. - * @returns { Promise[]> } Returns the asset download result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - download(table: string, gid: string, prefix: string, assets: CloudAsset[]): Promise[]>; - - /** - * Uploads assets. - * - * @param { string } table - Indicates the name of the table. - * @param { string } gid - Indicates the GID. - * @param { CloudAsset[] } assets - Indicates the assets to upload. - * @returns { Promise[]> } Returns the asset upload result. - * @syscap SystemCapability.DistributedDataManager.CloudSync.Server - * @systemapi - * @since 11 - */ - upload(table: string, gid: string, assets: CloudAsset[]): Promise[]>; - } - /** * Provides interfaces for implementing ShareCenter. * @@ -1100,13 +96,13 @@ declare namespace cloudExtension { */ export interface ShareCenter { /** - * Share data with specific participants. + * Shares data with specific participants. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the {@link Participant}. - * @returns { Promise>>> } Returns the sharing result. + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participant. + * @returns { Promise>>> } Returns the sharing result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 @@ -1114,18 +110,18 @@ declare namespace cloudExtension { share( userId: number, bundleName: string, - sharingRes: string, - participants: Array - ): Promise>>>; + sharingResource: string, + participants: Array + ): Promise>>>; /** - * Unshare data with specific participants. + * UnShares data with specific participants. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the {@link Participant}. - * @returns { Promise>>> } Returns the sharing result. + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participant. + * @returns { Promise>>> } Returns the sharing result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 @@ -1133,31 +129,31 @@ declare namespace cloudExtension { unshare( userId: number, bundleName: string, - sharingRes: string, - participants: Array - ): Promise>>>; + sharingResource: string, + participants: Array + ): Promise>>>; /** - * Exit the sharing. + * Exits the sharing. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. + * @param { string } sharingResource - Indicates the sharing resource. * @returns { Promise> } Returns the exit result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 */ - exit(userId: number, bundleName: string, sharingRes: string): Promise>; + exit(userId: number, bundleName: string, sharingResource: string): Promise>; /** * Changes privilege of the specific participants. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. - * @param { Array } participants - Indicates the {@link Participant}. - * @returns { Promise>>> } Returns the changing result. + * @param { string } sharingResource - Indicates the sharing resource. + * @param { Array } participants - Indicates the participant. + * @returns { Promise>>> } Returns the changing result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 @@ -1165,17 +161,17 @@ declare namespace cloudExtension { changePrivilege( userId: number, bundleName: string, - sharingRes: string, - participants: Array - ): Promise>>>; + sharingResource: string, + participants: Array + ): Promise>>>; /** - * Query participants of the specific sharing resource. + * Queries participants of the specific sharing resource. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. - * @returns { Promise>> } Returns the query result. + * @param { string } sharingResource - Indicates the sharing resource. + * @returns { Promise>> } Returns the query result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 @@ -1183,16 +179,16 @@ declare namespace cloudExtension { queryParticipants( userId: number, bundleName: string, - sharingRes: string - ): Promise>>; + sharingResource: string + ): Promise>>; /** - * Query participants based on the specified invitation code. + * Queries participants based on the specified invitation code. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. * @param { string } invitationCode - Indicates the invitation code. - * @returns { Promise>> } Returns the query result. + * @returns { Promise>> } Returns the query result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi * @since 11 @@ -1201,7 +197,7 @@ declare namespace cloudExtension { userId: number, bundleName: string, invitationCode: string - ): Promise>>; + ): Promise>>; /** * Confirms invitation. @@ -1209,7 +205,7 @@ declare namespace cloudExtension { * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. * @param { string } invitationCode - Indicates the invitation code. - * @param { ParticipantStatus } status - Indicates the {@link ParticipantStatus}. + * @param { cloudData.sharing.State } state - Indicates the state. * @returns { Promise> } Returns the sharing resource. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi @@ -1219,16 +215,16 @@ declare namespace cloudExtension { userId: number, bundleName: string, invitationCode: string, - status: ParticipantStatus - ): Promise>; + state: cloudData.sharing.State + ): Promise>; /** * Changes confirmation. * * @param { number } userId - Indicates the user ID. * @param { string } bundleName - Indicates the bundle name. - * @param { string } sharingRes - Indicates the sharing resource. - * @param { ParticipantStatus } status - Indicates the {@link ParticipantStatus}. + * @param { string } sharingResource - Indicates the sharing resource. + * @param { cloudData.sharing.State } state - Indicates the state. * @returns { Promise> } Returns the change result. * @syscap SystemCapability.DistributedDataManager.CloudSync.Server * @systemapi @@ -1237,10 +233,32 @@ declare namespace cloudExtension { changeConfirmation( userId: number, bundleName: string, - sharingRes: string, - status: ParticipantStatus + sharingResource: string, + state: cloudData.sharing.State ): Promise>; } + + /** + * Provides interfaces for implementing CloudService. + * + * @interface CloudService + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server + * @systemapi + * @since 11 + */ + export interface CloudService { + /** + * Connects to a share center. + * + * @param { number } userId - Indicates the user ID. + * @param { string } bundleName - Indicates the bundle name. + * @returns { Promise } Returns shareCenter RemoteObject. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Server + * @systemapi + * @since 11 + */ + connectShareCenter(userId: number, bundleName: string): Promise; + } } export default cloudExtension; \ No newline at end of file diff --git a/interface_sdk/api/@ohos.data.dataAbility.d.ts b/interface_sdk/api/@ohos.data.dataAbility.d.ts index bf4a7fe4..5f9a92b3 100644 --- a/interface_sdk/api/@ohos.data.dataAbility.d.ts +++ b/interface_sdk/api/@ohos.data.dataAbility.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback } from './@ohos.base'; import rdb from './@ohos.data.rdb'; diff --git a/interface_sdk/api/@ohos.data.dataShare.d.ts b/interface_sdk/api/@ohos.data.dataShare.d.ts index a23fcabb..48a43fd7 100644 --- a/interface_sdk/api/@ohos.data.dataShare.d.ts +++ b/interface_sdk/api/@ohos.data.dataShare.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import type { AsyncCallback } from './@ohos.base'; import Context from './application/Context'; import DataShareResultSet from './@ohos.data.DataShareResultSet'; diff --git a/interface_sdk/api/@ohos.data.dataSharePredicates.d.ts b/interface_sdk/api/@ohos.data.dataSharePredicates.d.ts index 92bf85b8..9eda70c1 100644 --- a/interface_sdk/api/@ohos.data.dataSharePredicates.d.ts +++ b/interface_sdk/api/@ohos.data.dataSharePredicates.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { ValueType } from './@ohos.data.ValuesBucket'; /** diff --git a/interface_sdk/api/@ohos.data.distributedData.d.ts b/interface_sdk/api/@ohos.data.distributedData.d.ts index 08d01c22..d5d426b0 100644 --- a/interface_sdk/api/@ohos.data.distributedData.d.ts +++ b/interface_sdk/api/@ohos.data.distributedData.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; /** diff --git a/interface_sdk/api/@ohos.data.distributedDataObject.d.ts b/interface_sdk/api/@ohos.data.distributedDataObject.d.ts index ca989b6a..7b733a7b 100644 --- a/interface_sdk/api/@ohos.data.distributedDataObject.d.ts +++ b/interface_sdk/api/@ohos.data.distributedDataObject.d.ts @@ -13,8 +13,14 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; import type Context from './application/BaseContext'; +import commonType from '@ohos.data.commonType'; /** * Provides interfaces to sync distributed object. @@ -24,6 +30,61 @@ import type Context from './application/BaseContext'; * @since 8 */ declare namespace distributedDataObject { + /** + * The information about the database bound to the asset. + * + * @interface BindInfo + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + interface BindInfo { + /** + * The name of store where the asset resides. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + storeName: string; + + /** + * The name of table where the asset resides. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + tableName: string; + + /** + * The Primary key of the rdb table where the asset resides. + * + * @type { commonType.ValuesBucket } + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + primaryKey: commonType.ValuesBucket; + + /** + * The field(column) name of the rdb table where the asset resides. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + field: string; + + /** + * Name of the asset to be bound. When the column type is Assets, this field refers to the asset name of + * one of the assets. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + assetName: string; + } + /** * Create distributed object. * @@ -395,6 +456,32 @@ declare namespace distributedDataObject { * @since 9 */ revokeSave(): Promise; + + /** + * Bind an Asset of a distributed object to an asset in rdb that points to the same asset file, which means that + * both assets have the same uri. + * @param { string } assetKey - Indicates the key of the asset type in Object. + * @param { BindInfo } bindInfo - Indicates the information of the asset in RelationalStore. + * @param { AsyncCallback } callback - The callback of bindAssetStore. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + bindAssetStore(assetKey: string, bindInfo: BindInfo, callback: AsyncCallback): void; + + /** + * Bind an Asset of a distributed object to an asset in rdb that points to the same asset file, which means that + * both assets have the same uri. + * @param { string } assetKey - Indicates the key of the asset type in Object. + * @param { BindInfo } bindInfo - Indicates the information of the asset in RelationalStore. + * @returns { Promise } The promise returned by the function. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.DataObject.DistributedObject + * @since 11 + */ + bindAssetStore(assetKey: string, bindInfo: BindInfo): Promise; } } diff --git a/interface_sdk/api/@ohos.data.distributedKVStore.d.ts b/interface_sdk/api/@ohos.data.distributedKVStore.d.ts index 836cdacd..4201976b 100644 --- a/interface_sdk/api/@ohos.data.distributedKVStore.d.ts +++ b/interface_sdk/api/@ohos.data.distributedKVStore.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; import { ValuesBucket } from './@ohos.data.ValuesBucket'; import dataSharePredicates from './@ohos.data.dataSharePredicates'; diff --git a/interface_sdk/api/@ohos.data.preferences.d.ts b/interface_sdk/api/@ohos.data.preferences.d.ts index a0cd2710..2fa6950e 100644 --- a/interface_sdk/api/@ohos.data.preferences.d.ts +++ b/interface_sdk/api/@ohos.data.preferences.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; import Context from './application/BaseContext'; @@ -838,6 +843,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @param { AsyncCallback } callback - The value matching the specified key if it is found; * returns the default value otherwise. @@ -850,6 +856,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @param { AsyncCallback } callback - The value matching the specified key if it is found; * returns the default value otherwise. @@ -863,6 +870,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @param { AsyncCallback } callback - The value matching the specified key if it is found; * returns the default value otherwise. @@ -879,6 +887,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @returns { Promise } The value matching the specified key if it is found; * returns the default value otherwise. @@ -891,6 +900,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @returns { Promise } The value matching the specified key if it is found; * returns the default value otherwise. @@ -904,6 +914,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @returns { Promise } The value matching the specified key if it is found; * returns the default value otherwise. @@ -920,6 +931,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @returns { ValueType } The value matching the specified key if it is found; * returns the default value otherwise. @@ -933,6 +945,7 @@ declare namespace preferences { *

If the value is {@code null} or not in the ValueType format, the default value is returned. * * @param { string } key - Indicates the key of the preferences. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { ValueType } defValue - Indicates the default value to return. * @returns { ValueType } The value matching the specified key if it is found; * returns the default value otherwise. @@ -1029,6 +1042,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { AsyncCallback } callback - {@code true} if the {@link Preferences} object contains a preferences * with the specified key;returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1039,6 +1053,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { AsyncCallback } callback - {@code true} if the {@link Preferences} object contains a preferences * with the specified key;returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1050,6 +1065,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @param { AsyncCallback } callback - {@code true} if the {@link Preferences} object contains a preferences * with the specified key;returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1064,6 +1080,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @returns { Promise } {@code true} if the {@link Preferences} object contains * a preferences with the specified key; returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1074,6 +1091,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @returns { Promise } {@code true} if the {@link Preferences} object contains * a preferences with the specified key; returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1085,6 +1103,7 @@ declare namespace preferences { * Checks whether the {@link Preferences} object contains a preferences matching a specified key. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @returns { Promise } {@code true} if the {@link Preferences} object contains * a preferences with the specified key; returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1100,6 +1119,7 @@ declare namespace preferences { * is executed synchronously. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @returns { boolean } {@code true} if the {@link Preferences} object contains * a preferences with the specified key; returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. @@ -1112,6 +1132,7 @@ declare namespace preferences { * is executed synchronously. * * @param { string } key - Indicates the key of the preferences to modify. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. * @returns { boolean } {@code true} if the {@link Preferences} object contains * a preferences with the specified key; returns {@code false} otherwise. * @throws { BusinessError } 401 - Parameter error. diff --git a/interface_sdk/api/@ohos.data.rdb.d.ts b/interface_sdk/api/@ohos.data.rdb.d.ts index b2f76b8d..68610800 100644 --- a/interface_sdk/api/@ohos.data.rdb.d.ts +++ b/interface_sdk/api/@ohos.data.rdb.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; import { ResultSet as _ResultSet } from './data/rdb/resultSet'; import Context from './application/BaseContext'; diff --git a/interface_sdk/api/@ohos.data.relationalStore.d.ts b/interface_sdk/api/@ohos.data.relationalStore.d.ts index da0091ce..9e7af0cf 100644 --- a/interface_sdk/api/@ohos.data.relationalStore.d.ts +++ b/interface_sdk/api/@ohos.data.relationalStore.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; import Context from './application/BaseContext'; import dataSharePredicates from './@ohos.data.dataSharePredicates'; @@ -762,6 +767,49 @@ declare namespace relationalStore { DISTRIBUTED_CLOUD } + /** + * Indicates the reference between tables. + * + * @interface Reference + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @systemapi + * @since 11 + */ + interface Reference { + /** + * Indicates the table that references another table. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @systemapi + * @since 11 + */ + sourceTable: string; + + /** + * Indicates the table to be referenced. + * + * @type { string } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @systemapi + * @since 11 + */ + targetTable: string; + + /** + * Indicates the reference fields. + * + * @type { object } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @systemapi + * @since 11 + */ + refFields: { + [src: string]: string; + }; + } + + /** * Manages the distributed configuration of the table. * @@ -777,6 +825,16 @@ declare namespace relationalStore { * @since 10 */ autoSync: boolean; + + /** + * Specifies the reference relationships between tables. + * + * @type { ?Array } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @systemapi + * @since 11 + */ + references?: Array; } /** @@ -923,7 +981,15 @@ declare namespace relationalStore { * @syscap SystemCapability.DistributedDataManager.CloudSync.Client * @since 11 */ - PRIVILEGE_FIELD = '#_cloud_privilege' + PRIVILEGE_FIELD = '#_cloud_privilege', + + /** + * Sharing resource field. + * + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @since 11 + */ + SHARING_RESOURCE_FIELD = '#_sharing_resource_field' } /** @@ -2909,6 +2975,53 @@ declare namespace relationalStore { */ cleanDirtyData(table: string, cursor?: number): Promise; + /** + * Obtains sharing resource of rows corresponding to the predicates. + * + * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. + * @param { Array } [columns] - The specified columns to query. + * @returns { Promise } -The promise returned by the function. + * {@link ResultSet} is query result. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 14800000 - Inner error. + * @throws { BusinessError } 401 - Parameter error. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + querySharingResource(predicates: RdbPredicates, columns?: Array): Promise; + + /** + * Obtains sharing resource of rows corresponding to the predicates. + * + * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. + * @param { AsyncCallback } callback - The callback of querySharingResource. + * {@link ResultSet} is query result. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 14800000 - Inner error. + * @throws { BusinessError } 401 - Parameter error. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + querySharingResource(predicates: RdbPredicates, callback: AsyncCallback): void; + + /** + * Obtains sharing resource of rows corresponding to the predicates. + * + * @param { RdbPredicates } predicates - The specified query condition by the instance object of {@link RdbPredicates}. + * @param { Array } columns - The specified columns to query. + * @param { AsyncCallback } callback - The callback of querySharingResource. + * {@link ResultSet} is query result. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 14800000 - Inner error. + * @throws { BusinessError } 401 - Parameter error. + * @syscap SystemCapability.DistributedDataManager.CloudSync.Client + * @systemapi + * @since 11 + */ + querySharingResource(predicates: RdbPredicates, columns: Array, callback: AsyncCallback): void; + /** * Executes a SQL statement that contains specified parameters but returns no value. * diff --git a/interface_sdk/api/@ohos.data.storage.d.ts b/interface_sdk/api/@ohos.data.storage.d.ts index a68f1227..f24cfb70 100644 --- a/interface_sdk/api/@ohos.data.storage.d.ts +++ b/interface_sdk/api/@ohos.data.storage.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback, Callback } from './@ohos.base'; /** @@ -25,6 +30,8 @@ import { AsyncCallback, Callback } from './@ohos.base'; * @syscap SystemCapability.DistributedDataManager.Preferences.Core * */ + + declare namespace storage { /** * Obtains a {@link Storage} instance matching a specified storage file name. diff --git a/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts b/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts index 05feb6b2..2c3b5f99 100644 --- a/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts +++ b/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + import { AsyncCallback } from './@ohos.base'; /** diff --git a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts index 7b66fd9e..94cc4277 100644 --- a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts +++ b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts @@ -13,6 +13,11 @@ * limitations under the License. */ +/** + * @file + * @kit ArkData + */ + /** * Provides methods for uniform data type definition and query. * diff --git a/kv_store/bundle.json b/kv_store/bundle.json index 0b5a986f..a1e55e77 100644 --- a/kv_store/bundle.json +++ b/kv_store/bundle.json @@ -66,6 +66,7 @@ "common_event_service", "c_utils", "device_manager", + "ffrt", "hilog", "hisysevent", "hitrace", diff --git a/kv_store/frameworks/common/itypes_util.h b/kv_store/frameworks/common/itypes_util.h index ceebec5d..4d685bf9 100644 --- a/kv_store/frameworks/common/itypes_util.h +++ b/kv_store/frameworks/common/itypes_util.h @@ -138,6 +138,16 @@ static inline bool Unmarshalling(std::string &output, MessageParcel &data) return data.ReadString(output); } +static inline bool Marshalling(const std::u16string &input, MessageParcel &data) +{ + return data.WriteString16(input); +} + +static inline bool Unmarshalling(std::u16string &output, MessageParcel &data) +{ + return data.ReadString16(output); +} + static inline bool Marshalling(const std::vector &input, MessageParcel &data) { return data.WriteUInt8Vector(input); diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h b/kv_store/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h index 5c20d5ea..1ad20722 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h +++ b/kv_store/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h @@ -14,19 +14,18 @@ */ #ifndef OHOS_KV_STORE_RESELTSET_H #define OHOS_KV_STORE_RESELTSET_H +#include "js_proxy.h" +#include "kvstore_result_set.h" #include "napi_queue.h" #include "result_set_bridge.h" -#include "kvstore_result_set.h" namespace OHOS::DistributedData { -class JsKVStoreResultSet : public DataShare::ResultSetBridge::Creator { +class JsKVStoreResultSet : public JSProxy::JSEntity { public: JsKVStoreResultSet() = default; virtual ~JsKVStoreResultSet() = default; - void SetNative(std::shared_ptr& resultSet); void SetSchema(bool isSchema); - std::shared_ptr& GetNative(); static napi_value Constructor(napi_env env); static napi_value New(napi_env env, napi_callback_info info); @@ -48,7 +47,6 @@ private: static napi_value IsAfterLast(napi_env env, napi_callback_info info); static napi_value GetEntry(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_ = nullptr; bool isSchema_ = false; }; } // namespace OHOS::DistributedData diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp index 4d6efe75..5f4748ca 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp @@ -285,7 +285,7 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) }; ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); - ctxt->resultSet->SetNative(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -323,7 +323,9 @@ napi_value JsDeviceKVStore::CloseResultSet(napi_env env, napi_callback_info info auto execute = [ctxt]() { auto& kvStore = reinterpret_cast(ctxt->native)->GetNative(); - Status status = kvStore->CloseResultSet(ctxt->resultSet->GetNative()); + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); + Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->CloseResultSet failed!"); diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp index 2864faa9..7afeffc9 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp @@ -15,11 +15,13 @@ #define LOG_TAG "JsKVStore" #include "js_kv_store.h" #include "js_util.h" +#include "js_kv_store_resultset.h" #include "log_print.h" #include "napi_queue.h" #include "datashare_values_bucket.h" #include "datashare_predicates.h" #include "single_kvstore.h" +#include "kv_utils.h" using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp index b81d9b68..7b8b5ac3 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp @@ -22,15 +22,6 @@ using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; namespace OHOS::DistributedData { -void JsKVStoreResultSet::SetNative(std::shared_ptr& resultSet) -{ - resultSet_ = resultSet; -} - -std::shared_ptr& JsKVStoreResultSet::GetNative() -{ - return resultSet_; -} napi_value JsKVStoreResultSet::Constructor(napi_env env) { @@ -81,7 +72,7 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -95,7 +86,7 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -109,7 +100,7 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -123,7 +114,7 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -137,7 +128,7 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -151,7 +142,7 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -171,7 +162,7 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo ctxt->GetCbInfoSync(env, info, input); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -191,7 +182,7 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -205,7 +196,7 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -219,7 +210,7 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -233,7 +224,7 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -247,7 +238,7 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -262,7 +253,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); DistributedKv::Entry entry; - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -276,7 +267,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(resultSet_); + return KvUtils::ToResultSetBridge(GetInstance()); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp index b03e2a2d..841df33d 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp @@ -235,7 +235,7 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); - ctxt->resultSet->SetNative(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -273,7 +273,9 @@ napi_value JsSingleKVStore::CloseResultSet(napi_env env, napi_callback_info info auto execute = [ctxt]() { auto& kvStore = reinterpret_cast(ctxt->native)->GetNative(); - Status status = kvStore->CloseResultSet(ctxt->resultSet->GetNative()); + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); + Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->CloseResultSet failed!"); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h index 8fb9ee62..a952f240 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h @@ -15,18 +15,17 @@ #ifndef OHOS_KV_STORE_RESELTSET_H #define OHOS_KV_STORE_RESELTSET_H #include "napi_queue.h" +#include "js_proxy.h" #include "result_set_bridge.h" #include "kvstore_result_set.h" namespace OHOS::DistributedKVStore { -class JsKVStoreResultSet : public DataShare::ResultSetBridge::Creator { +class JsKVStoreResultSet : public JSProxy::JSEntity { public: JsKVStoreResultSet() = default; virtual ~JsKVStoreResultSet() = default; - void SetKvStoreResultSetPtr(std::shared_ptr resultSet); void SetSchema(bool isSchema); - std::shared_ptr GetKvStoreResultSetPtr(); static napi_value Constructor(napi_env env); static napi_value New(napi_env env, napi_callback_info info); @@ -48,7 +47,6 @@ private: static napi_value IsAfterLast(napi_env env, napi_callback_info info); static napi_value GetEntry(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_ = nullptr; bool isSchema_ = false; }; } // namespace OHOS::DistributedKVStore diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp index 83ce1911..e7e94a1e 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp @@ -254,7 +254,7 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) ZLOGD("kvStore->GetResultSet() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; - ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp index c19a9499..5de48703 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp @@ -24,15 +24,6 @@ using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; namespace OHOS::DistributedKVStore { -void JsKVStoreResultSet::SetKvStoreResultSetPtr(std::shared_ptr resultSet) -{ - resultSet_ = resultSet; -} - -std::shared_ptr JsKVStoreResultSet::GetKvStoreResultSetPtr() -{ - return resultSet_; -} napi_value JsKVStoreResultSet::Constructor(napi_env env) { @@ -86,7 +77,7 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -100,7 +91,7 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -114,7 +105,7 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -128,7 +119,7 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -142,7 +133,7 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -156,7 +147,7 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -177,7 +168,7 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo ASSERT_NULL(!ctxt->isThrowError, "Move exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function MoveV9 parameter is incorrect."); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -199,7 +190,7 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i "The function MoveToPositionV9 parameter is incorrect."); ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -213,7 +204,7 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -227,7 +218,7 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -241,7 +232,7 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -255,7 +246,7 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -270,7 +261,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); DistributedKv::Entry entry; - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -284,7 +275,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(resultSet_); + return KvUtils::ToResultSetBridge(GetInstance()); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp index 5a0017b6..5f500d21 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp @@ -1008,7 +1008,7 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; - ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -1048,7 +1048,8 @@ napi_value JsSingleKVStore::CloseResultSet(napi_env env, napi_callback_info info auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); - auto resultSet = ctxt->resultSet->GetKvStoreResultSetPtr(); + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? diff --git a/kv_store/frameworks/libs/distributeddb/BUILD.gn b/kv_store/frameworks/libs/distributeddb/BUILD.gn index 6c4d513c13..47cac80c 100644 --- a/kv_store/frameworks/libs/distributeddb/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/BUILD.gn @@ -62,6 +62,9 @@ config("distrdb_config") { if (is_debug) { defines += [ "TRACE_SQLITE_EXECUTE" ] } + if (is_ohos) { + defines += [ "USE_FFRT" ] + } } config("distrdb_public_config") { @@ -102,6 +105,7 @@ ohos_shared_library("distributeddb") { external_deps = [ "c_utils:utils", + "ffrt:libffrt", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", diff --git a/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h b/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h index d1873161..0379d4dd 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h @@ -177,6 +177,13 @@ protected: std::string GetAutoLaunchItemUid(const std::string &identifier, const std::string &originalUserId, bool &handleByCallback); + bool ChkAutoLaunchAbort(const std::string &identifier, AutoLaunchItem &autoLaunchItem); + + void NotifyAutoLaunch(const std::string &userId, AutoLaunchItem &autoLaunchItem, AutoLaunchNotifier ¬ifier); + + void AutoLaunchOnChange(const std::string &changedDevice, std::string userId, std::string appId, + std::string storeId, AutoLaunchItem autoLaunchItem); + mutable std::mutex dataLock_; mutable std::mutex communicatorLock_; std::set onlineDevices_; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h index bbac5d32..29693f4b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_constant.h @@ -39,10 +39,12 @@ public: static constexpr const char *SHARED = "_shared"; static constexpr const char *CLOUD_OWNER = "cloud_owner"; static constexpr const char *CLOUD_PRIVILEGE = "cloud_privilege"; + static constexpr const char *DEFAULT_CLOUD_DEV = "cloud"; static constexpr uint32_t MAX_UPLOAD_SIZE = 1024 * 512 * 3; // 1.5M // cloud data timestamp is utc ms precision // used for 100ns to ms when handle cloud data timestamp static constexpr uint32_t TEN_THOUSAND = 10000; + static constexpr int64_t CLOUD_DEFAULT_TIMEOUT = -1; }; } // namespace DistributedDB #endif // CLOUD_DB_CONSTANT_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h index 1fc3b399..406c1321 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h @@ -104,6 +104,10 @@ public: const std::map &nodeWeight); static bool HasPrimaryKey(const std::vector &fields); + + static bool IsRecordError(const VBucket &record); + + static bool IsRecordIgnored(const VBucket &record); private: static void InsertNodesByScore(const std::map> &graph, const std::vector &generateNodes, const std::map &scoreGraph, diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h index a99f76b3..82436245 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h @@ -178,6 +178,7 @@ public: static constexpr const char *TABLE_IS_DROPPED = "table_is_dropped_"; static constexpr const char *SQLITE_INNER_ROWID = "_rowid_"; + static constexpr int32_t DEFAULT_ROW_ID = -1; }; } // namespace DistributedDB #endif // DISTRIBUTEDDB_CONSTANT_H diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_dfx_adapter.h b/kv_store/frameworks/libs/distributeddb/common/include/db_dfx_adapter.h index c3f9968e..ef8ab5e9 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_dfx_adapter.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_dfx_adapter.h @@ -43,7 +43,7 @@ public: static void FinishTrace(); static void StartTracing(); - static void FinishTraceSQL(); + static void FinishTracing(); static void StartAsyncTrace(const std::string &action, int32_t taskId); static void FinishAsyncTrace(const std::string &action, int32_t taskId); diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h index a6c8d42d..42606c2b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h @@ -138,6 +138,8 @@ constexpr int E_CLOUD_ASSET_SPACE_INSUFFICIENT = (E_BASE + 117); // cloud failed constexpr int E_CLOUD_INVALID_ASSET = (E_BASE + 118); // the asset is invalid constexpr int E_TASK_PAUSED = (E_BASE + 119); // the task was paused, don't finished it constexpr int E_CLOUD_VERSION_CONFLICT = (E_BASE + 120); // cloud failed to update version +constexpr int E_CLOUD_RECORD_EXIST_CONFLICT = (E_BASE + 121); // record conflict when upload/download +constexpr int E_REMOVE_ASSETS_FAILED = (E_BASE + 122); // remove local assets failed // Num 150+ is reserved for schema related errno, since it may be added regularly constexpr int E_JSON_PARSE_FAIL = (E_BASE + 150); // Parse json fail in grammatical level constexpr int E_JSON_INSERT_PATH_EXIST = (E_BASE + 151); // Path already exist before insert diff --git a/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h b/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h index 63f04732..633243ab 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h @@ -125,6 +125,8 @@ public: bool Empty() const; + bool IsNoPkTable() const; + private: void AddFieldDefineString(std::string &attrStr) const; void AddIndexDefineString(std::string &attrStr) const; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp index 8d0ff7c1..dc7b49d0 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp @@ -31,6 +31,7 @@ #include "runtime_context.h" #include "semaphore_utils.h" #include "sync_able_kvdb_connection.h" +#include "concurrent_adapter.h" namespace DistributedDB { namespace { @@ -734,12 +735,15 @@ EXT: void AutoLaunch::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBTypeInner type) { LOGI("[AutoLaunch] SetAutoLaunchRequestCallback type[%d]", static_cast(type)); - std::lock_guard lock(extLock_); - if (callback) { - autoLaunchRequestCallbackMap_[type] = callback; - } else { - autoLaunchRequestCallbackMap_.erase(type); - } + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, callback, type] () mutable { + ADAPTER_AUTO_LOCK(lock, extLock_); + if (callback) { + autoLaunchRequestCallbackMap_[type] = callback; + } else { + autoLaunchRequestCallbackMap_.erase(type); + } + }, {}, {&autoLaunchRequestCallbackMap_}); + ADAPTER_WAIT(handle); } int AutoLaunch::AutoLaunchExt(const std::string &identifier, const std::string &userId) @@ -785,45 +789,41 @@ void AutoLaunch::AutoLaunchExtTask(const std::string &identifier, const std::str AutoLaunchItem &autoLaunchItem) { { - std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0) { - LOGE("[AutoLaunch] extItemMap has this identifier"); + bool isReturn = false; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, + &autoLaunchItem, &isReturn] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0) { + LOGE("[AutoLaunch] extItemMap has this identifier"); + isReturn = true; + return; + } + extItemMap_[identifier][userId] = autoLaunchItem; + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); + if (isReturn) { return; } - extItemMap_[identifier][userId] = autoLaunchItem; } - bool abort = false; - do { - int errCode = CheckAutoLaunchRealPath(autoLaunchItem); - if (errCode != E_OK) { - abort = true; - break; - } - errCode = OpenOneConnection(autoLaunchItem); - LOGI("[AutoLaunch] AutoLaunchExtTask GetOneConnection errCode:%d", errCode); - if (autoLaunchItem.conn == nullptr) { - abort = true; - break; - } - errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, true); - if (errCode != E_OK) { - LOGE("[AutoLaunch] AutoLaunchExtTask RegisterObserverAndLifeCycleCallback failed"); - TryCloseConnection(autoLaunchItem); // if here failed, do nothing - abort = true; - } - } while (false); + bool abort = ChkAutoLaunchAbort(identifier, autoLaunchItem); if (abort) { - std::lock_guard autoLock(extLock_); - extItemMap_[identifier].erase(userId); - if (extItemMap_[identifier].size() == 0) { - extItemMap_.erase(identifier); - } + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); return; } - std::lock_guard autoLock(extLock_); - extItemMap_[identifier][userId] = autoLaunchItem; // Reassign item to prevent it from being erased - extItemMap_[identifier][userId].isWriteOpenNotified = false; - LOGI("[AutoLaunch] AutoLaunchExtTask ok"); + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, &autoLaunchItem] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + extItemMap_[identifier][userId] = autoLaunchItem; // Reassign item to prevent it from being erased + extItemMap_[identifier][userId].isWriteOpenNotified = false; + LOGI("[AutoLaunch] AutoLaunchExtTask ok"); + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); } void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const std::string &identifier, @@ -833,12 +833,21 @@ void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const s AutoLaunchItem autoLaunchItem; AutoLaunchNotifier notifier; { - std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { - LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map"); + bool isReturn = false; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, + &autoLaunchItem, &isReturn] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { + LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map"); + isReturn = true; + return; + } + autoLaunchItem = extItemMap_[identifier][userId]; + }, {&extItemMap_}, {}); + ADAPTER_WAIT(handle); + if (isReturn) { return; } - autoLaunchItem = extItemMap_[identifier][userId]; } if (autoLaunchItem.observer != nullptr) { LOGD("[AutoLaunch] do user observer"); @@ -847,26 +856,26 @@ void AutoLaunch::ExtObserverFunc(const KvDBCommitNotifyData ¬ifyData, const s } { - std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0 && - !extItemMap_[identifier][userId].isWriteOpenNotified && - autoLaunchItem.notifier != nullptr) { - extItemMap_[identifier][userId].isWriteOpenNotified = true; - notifier = autoLaunchItem.notifier; - } else { + bool isReturn = false; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, &autoLaunchItem, + ¬ifier, &isReturn] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (extItemMap_.count(identifier) != 0 && extItemMap_[identifier].count(userId) != 0 && + !extItemMap_[identifier][userId].isWriteOpenNotified && + autoLaunchItem.notifier != nullptr) { + extItemMap_[identifier][userId].isWriteOpenNotified = true; + notifier = autoLaunchItem.notifier; + } else { + isReturn = true; + } + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); + if (isReturn) { return; } } - std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::APP_ID, ""); - std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::STORE_ID, ""); - int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] { - LOGI("[AutoLaunch] ExtObserverFunc do user notifier WRITE_OPENED"); - notifier(userId, appId, storeId, AutoLaunchStatus::WRITE_OPENED); - }); - if (retCode != E_OK) { - LOGE("[AutoLaunch] ExtObserverFunc notifier ScheduleTask retCode:%d", retCode); - } + NotifyAutoLaunch(userId, autoLaunchItem, notifier); } void AutoLaunch::ExtConnectionLifeCycleCallback(const std::string &identifier, const std::string &userId) @@ -884,16 +893,25 @@ void AutoLaunch::ExtConnectionLifeCycleCallbackTask(const std::string &identifie LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier=%.6s", STR_TO_HEX(identifier)); AutoLaunchItem autoLaunchItem; { - std::lock_guard autoLock(extLock_); - if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { - LOGE("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier is not exist!"); + bool isReturn = false; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, + &autoLaunchItem, &isReturn] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (extItemMap_.count(identifier) == 0 || extItemMap_[identifier].count(userId) == 0) { + LOGE("[AutoLaunch] ExtConnectionLifeCycleCallbackTask identifier is not exist!"); + isReturn = true; + return; + } + autoLaunchItem = extItemMap_[identifier][userId]; + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); + if (isReturn) { return; } - autoLaunchItem = extItemMap_[identifier][userId]; - extItemMap_[identifier].erase(userId); - if (extItemMap_[identifier].size() == 0) { - extItemMap_.erase(identifier); - } } LOGI("[AutoLaunch] ExtConnectionLifeCycleCallbackTask do CloseConnection"); TryCloseConnection(autoLaunchItem); // do nothing if failed @@ -1034,26 +1052,33 @@ int AutoLaunch::GetAutoLaunchRelationProperties(const AutoLaunchParam ¶m, int AutoLaunch::ExtAutoLaunchRequestCallBack(const std::string &identifier, AutoLaunchParam ¶m, DBTypeInner &openType) { - std::lock_guard lock(extLock_); - if (autoLaunchRequestCallbackMap_.empty()) { - LOGI("[AutoLaunch] autoLaunchRequestCallbackMap_ is empty"); - return -E_NOT_FOUND; // not E_OK is ok for communicator - } + int errCode = E_OK; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, ¶m, &errCode, &openType] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (autoLaunchRequestCallbackMap_.empty()) { + LOGI("[AutoLaunch] autoLaunchRequestCallbackMap_ is empty"); + errCode = -E_NOT_FOUND; // not E_OK is ok for communicator + return errCode; + } - bool needOpen = false; - for (const auto &[type, callBack] : autoLaunchRequestCallbackMap_) { - needOpen = callBack(identifier, param); - if (needOpen) { - openType = type; - break; + bool needOpen = false; + for (const auto &[type, callBack] : autoLaunchRequestCallbackMap_) { + needOpen = callBack(identifier, param); + if (needOpen) { + openType = type; + break; + } } - } - if (!needOpen) { - LOGI("[AutoLaunch] autoLaunchRequestCallback is not need open"); - return -E_NOT_FOUND; // not E_OK is ok for communicator - } - return E_OK; + if (!needOpen) { + LOGI("[AutoLaunch] autoLaunchRequestCallback is not need open"); + errCode = -E_NOT_FOUND; // not E_OK is ok for communicator + return errCode; + } + return E_OK; + }, {&autoLaunchRequestCallbackMap_}, {}); + ADAPTER_WAIT(handle); + return errCode; } int AutoLaunch::OpenKvConnection(AutoLaunchItem &autoLaunchItem) @@ -1261,32 +1286,31 @@ int AutoLaunch::RegisterRelationalObserver(AutoLaunchItem &autoLaunchItem, const Origin::ORIGIN_CLOUD, changedDevice, std::move(changedData)); return; } - RelationalStoreChangedDataImpl data(changedDevice); std::string userId; std::string appId; std::string storeId; - if (autoLaunchItem.propertiesPtr != nullptr) { - userId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::USER_ID, ""); - appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, ""); - storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, ""); - data.SetStoreProperty({ userId, appId, storeId }); - } - if (autoLaunchItem.storeObserver) { - LOGD("begin to observer onchange, changedDevice=%s", STR_MASK(changedDevice)); - autoLaunchItem.storeObserver->OnChange(data); - } + AutoLaunchOnChange(changedDevice, userId, appId, storeId, autoLaunchItem); bool isWriteOpenNotified = false; AutoLaunchNotifier notifier = nullptr; { - std::lock_guard autoLock(extLock_); - if (extItemMap_.find(identifier) == extItemMap_.end() || - extItemMap_[identifier].find(userId) == extItemMap_[identifier].end()) { - LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map"); + bool isReturn = false; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId, + ¬ifier, &isWriteOpenNotified, &isReturn] () mutable { + ADAPTER_AUTO_LOCK(autoLock, extLock_); + if (extItemMap_.find(identifier) == extItemMap_.end() || + extItemMap_[identifier].find(userId) == extItemMap_[identifier].end()) { + LOGE("[AutoLaunch] ExtObserverFunc this identifier not in map"); + isReturn = true; + return; + } + notifier = extItemMap_[identifier][userId].notifier; + isWriteOpenNotified = extItemMap_[identifier][userId].isWriteOpenNotified; + extItemMap_[identifier][userId].isWriteOpenNotified = true; + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); + if (isReturn) { return; } - notifier = extItemMap_[identifier][userId].notifier; - isWriteOpenNotified = extItemMap_[identifier][userId].isWriteOpenNotified; - extItemMap_[identifier][userId].isWriteOpenNotified = true; } if (!isWriteOpenNotified && notifier != nullptr) { notifier(userId, appId, storeId, WRITE_OPENED); @@ -1299,46 +1323,50 @@ void AutoLaunch::CloseConnection(DBTypeInner type, const DBProperties &propertie { std::string identifier = properties.GetStringProp(DBProperties::IDENTIFIER_DATA, ""); int closeId = properties.GetIntProp(DBProperties::AUTO_LAUNCH_ID, 0); - std::lock_guard lock(extLock_); - auto itemMapIter = extItemMap_.find(identifier); - if (itemMapIter == extItemMap_.end()) { - std::string dualIdentifier = properties.GetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); - itemMapIter = extItemMap_.find(dualIdentifier); // Try find conn in dual tuple mode + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &properties, + closeId, type] () mutable { + ADAPTER_AUTO_LOCK(lock, extLock_); + auto itemMapIter = extItemMap_.find(identifier); if (itemMapIter == extItemMap_.end()) { - LOGD("[AutoLaunch] Abort close because not found id"); + std::string dualIdentifier = properties.GetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, ""); + itemMapIter = extItemMap_.find(dualIdentifier); // Try find conn in dual tuple mode + if (itemMapIter == extItemMap_.end()) { + LOGD("[AutoLaunch] Abort close because not found id"); + return; + } + identifier = dualIdentifier; + } + std::string userId = properties.GetStringProp(DBProperties::USER_ID, ""); + auto itemIter = itemMapIter->second.find(userId); + if (itemIter == itemMapIter->second.end()) { + LOGD("[AutoLaunch] Abort close because not found user id"); return; } - identifier = dualIdentifier; - } - std::string userId = properties.GetStringProp(DBProperties::USER_ID, ""); - auto itemIter = itemMapIter->second.find(userId); - if (itemIter == itemMapIter->second.end()) { - LOGD("[AutoLaunch] Abort close because not found user id"); - return; - } - if (itemIter->second.propertiesPtr == nullptr) { - LOGD("[AutoLaunch] Abort close because properties is invalid"); - return; - } - int targetId = itemIter->second.propertiesPtr->GetIntProp(DBProperties::AUTO_LAUNCH_ID, 0); - if (closeId != 0 && closeId != targetId) { - LOGD("[AutoLaunch] Abort close because connection has been closed"); - return; - } - if (itemIter->second.type != type) { - LOGE("[AutoLaunch] Not same DB type for close connection"); - return; - } - LOGI("[AutoLaunch] Force close connection"); - TryCloseConnection(itemIter->second); - if (itemIter->second.isWriteOpenNotified) { - CloseNotifier(itemIter->second); - } - LOGI("[AutoLaunch] Force close connection finished"); - extItemMap_[identifier].erase(userId); - if (extItemMap_[identifier].size() == 0) { - extItemMap_.erase(identifier); - } + if (itemIter->second.propertiesPtr == nullptr) { + LOGD("[AutoLaunch] Abort close because properties is invalid"); + return; + } + int targetId = itemIter->second.propertiesPtr->GetIntProp(DBProperties::AUTO_LAUNCH_ID, 0); + if (closeId != 0 && closeId != targetId) { + LOGD("[AutoLaunch] Abort close because connection has been closed"); + return; + } + if (itemIter->second.type != type) { + LOGE("[AutoLaunch] Not same DB type for close connection"); + return; + } + LOGI("[AutoLaunch] Force close connection"); + TryCloseConnection(itemIter->second); + if (itemIter->second.isWriteOpenNotified) { + CloseNotifier(itemIter->second); + } + LOGI("[AutoLaunch] Force close connection finished"); + extItemMap_[identifier].erase(userId); + if (extItemMap_[identifier].size() == 0) { + extItemMap_.erase(identifier); + } + }, {}, {&extItemMap_}); + ADAPTER_WAIT(handle); } std::string AutoLaunch::GetAutoLaunchItemUid(const std::string &identifier, const std::string &originalUserId, @@ -1372,4 +1400,59 @@ std::string AutoLaunch::GetAutoLaunchItemUid(const std::string &identifier, cons } return userId; } + +bool AutoLaunch::ChkAutoLaunchAbort(const std::string &identifier, AutoLaunchItem &autoLaunchItem) +{ + bool abort = false; + do { + int errCode = CheckAutoLaunchRealPath(autoLaunchItem); + if (errCode != E_OK) { + abort = true; + break; + } + errCode = OpenOneConnection(autoLaunchItem); + LOGI("[AutoLaunch] AutoLaunchExtTask GetOneConnection errCode:%d", errCode); + if (autoLaunchItem.conn == nullptr) { + abort = true; + break; + } + errCode = RegisterObserverAndLifeCycleCallback(autoLaunchItem, identifier, true); + if (errCode != E_OK) { + LOGE("[AutoLaunch] AutoLaunchExtTask RegisterObserverAndLifeCycleCallback failed"); + TryCloseConnection(autoLaunchItem); // if here failed, do nothing + abort = true; + } + } while (false); + return abort; +} + +void AutoLaunch::NotifyAutoLaunch(const std::string &userId, AutoLaunchItem &autoLaunchItem, + AutoLaunchNotifier ¬ifier) +{ + std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::APP_ID, ""); + std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::STORE_ID, ""); + int retCode = RuntimeContext::GetInstance()->ScheduleTask([notifier, userId, appId, storeId] { + LOGI("[AutoLaunch] ExtObserverFunc do user notifier WRITE_OPENED"); + notifier(userId, appId, storeId, AutoLaunchStatus::WRITE_OPENED); + }); + if (retCode != E_OK) { + LOGE("[AutoLaunch] ExtObserverFunc notifier ScheduleTask retCode:%d", retCode); + } +} + +void AutoLaunch::AutoLaunchOnChange(const std::string &changedDevice, std::string userId, std::string appId, + std::string storeId, AutoLaunchItem autoLaunchItem) +{ + RelationalStoreChangedDataImpl data(changedDevice); + if (autoLaunchItem.propertiesPtr != nullptr) { + userId = autoLaunchItem.propertiesPtr->GetStringProp(KvDBProperties::USER_ID, ""); + appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, ""); + storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, ""); + data.SetStoreProperty({ userId, appId, storeId }); + } + if (autoLaunchItem.storeObserver) { + LOGD("begin to observer onchange, changedDevice=%s", STR_MASK(changedDevice)); + autoLaunchItem.storeObserver->OnChange(data); + } +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp index 7e84c1be..a9cf311f 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -20,6 +20,7 @@ #include #include "cloud/cloud_db_constant.h" +#include "cloud/cloud_db_types.h" #include "db_errno.h" #include "platform_specific.h" #include "query_sync_object.h" @@ -599,4 +600,24 @@ bool DBCommon::HasPrimaryKey(const std::vector &fields) } return false; } + +bool DBCommon::IsRecordError(const VBucket &record) +{ + if (record.find(CloudDbConstant::ERROR_FIELD) == record.end()) { + return false; + } + return record.at(CloudDbConstant::ERROR_FIELD).index() == TYPE_INDEX; +} + +bool DBCommon::IsRecordIgnored(const VBucket &record) +{ + if (record.find(CloudDbConstant::ERROR_FIELD) == record.end()) { + return false; + } + if (record.at(CloudDbConstant::ERROR_FIELD).index() != TYPE_INDEX) { + return false; + } + auto status = std::get(record.at(CloudDbConstant::ERROR_FIELD)); + return status == static_cast(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_dfx_adapter.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_dfx_adapter.cpp index 6777efc9..a954aa12 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_dfx_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_dfx_adapter.cpp @@ -102,7 +102,7 @@ void DBDfxAdapter::StartTracing() #endif } -void DBDfxAdapter::FinishTraceSQL() +void DBDfxAdapter::FinishTracing() { #ifdef TRACE_SQLITE_EXECUTE ::FinishTrace(HITRACE_LABEL); @@ -153,7 +153,7 @@ void DBDfxAdapter::StartTracing() { } -void DBDfxAdapter::FinishTraceSQL() +void DBDfxAdapter::FinishTracing() { } #endif diff --git a/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp b/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp index fb74ea6d..2637c95a 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp @@ -457,4 +457,21 @@ void QueryExpression::SetNotSupportIfNeed(QueryObjType type) } } } + +int QueryExpression::IsRangeValid() const +{ + if (queryInfo_.size() > 1) { // Only Support one query filter. + return -E_INVALID_ARGS; + } + for (const auto &queryObjNode : queryInfo_) { + if (queryObjNode.operFlag != QueryObjType::KEY_RANGE) { + return -E_INVALID_ARGS; + } + } + if (this->beginKey_.size() > DBConstant::MAX_KEY_SIZE || + this->endKey_.size() > DBConstant::MAX_KEY_SIZE) { + return -E_INVALID_ARGS; + } + return E_OK; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp b/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp index f5579585..5ae2faac 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp @@ -795,4 +795,12 @@ const std::vector &TableInfo::GetTableReference() const { return sourceTableReferenced_; } + +bool TableInfo::IsNoPkTable() const +{ + if (primaryKey_.size() == 1 && primaryKey_.at(0) == ROW_ID) { + return true; + } + return false; +} } // namespace DistributeDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h index ed30b0d6..0480fe78 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h @@ -143,6 +143,14 @@ private: void ResetFrameRecordIfNeed(const uint32_t frameId, const uint32_t mtu); + void RetrySendTaskIfNeed(const std::string &target); + + void RetrySendTask(const std::string &target); + + bool IsRetryOutOfLimit(const std::string &target); + + int32_t GetNextRetryInterval(const std::string &target, int32_t currentRetryCount); + DECLARE_OBJECT_TAG(CommunicatorAggregator); static std::atomic isCommunicatorNotFoundFeedbackEnable_; @@ -195,6 +203,9 @@ private: }; std::mutex sendRecordMutex_; std::map sendRecord_; + + std::mutex retryCountMutex_; + std::map retryCount_; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h index 0d502030..4f624700 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h @@ -38,6 +38,7 @@ struct SendTask { std::string dstTarget; OnSendEnd onEnd; uint32_t frameId = 0u; + bool isValid = true; }; struct SendTaskInfo { @@ -76,6 +77,8 @@ public: uint32_t GetTotalTaskCount() const; uint32_t GetNoDelayTaskCount() const; + void InvalidSendTask(const std::string &target); + private: int ScheduleDelayTask(SendTask &outTask, SendTaskInfo &outTaskInfo); int ScheduleNoDelayTask(SendTask &outTask, SendTaskInfo &outTaskInfo); diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp index 41795384..d29bf92c 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -26,6 +26,8 @@ namespace DistributedDB { namespace { +constexpr int MAX_SEND_RETRY = 2; +constexpr int RETRY_TIME_SPLITS = 4; inline std::string GetThreadId() { std::stringstream stream; @@ -311,7 +313,7 @@ int CommunicatorAggregator::ScheduleSendTask(const std::string &dstTarget, Seria std::lock_guard autoLock(sendRecordMutex_); sendRecord_[info.frameId] = {}; } - SendTask task{inBuff, dstTarget, onEnd, info.frameId}; + SendTask task{inBuff, dstTarget, onEnd, info.frameId, true}; if (inConfig.nonBlock) { errCode = scheduler_.AddSendTaskIntoSchedule(task, inConfig.prio); } else { @@ -368,7 +370,7 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, u std::lock_guard autoLock(sendRecordMutex_); startIndex = sendRecord_[inTask.frameId].sendIndex; } - for (uint32_t index = startIndex; index < static_cast(eachPacket.size()); ++index) { + for (uint32_t index = startIndex; index < static_cast(eachPacket.size()) && inTask.isValid; ++index) { auto &entry = eachPacket[index]; LOGI("[CommAggr][SendPackets] DoSendBytes, dstTarget=%s{private}, extendHeadLength=%" PRIu32 ", packetLength=%" PRIu32 ".", inTask.dstTarget.c_str(), entry.second.first, entry.second.second); @@ -380,24 +382,18 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, u } if (errCode == -E_WAIT_RETRY) { LOGE("[CommAggr][SendPackets] SendBytes temporally fail."); - scheduler_.DelayTaskByTarget(inTask.dstTarget); taskNeedFinalize = false; break; } else if (errCode != E_OK) { LOGE("[CommAggr][SendPackets] SendBytes totally fail, errCode=%d.", errCode); break; + } else { + std::lock_guard autoLock(retryCountMutex_); + retryCount_[inTask.dstTarget] = 0; } } if (errCode == -E_WAIT_RETRY) { - const int RETRY_INTERVAL = 1000; // 1000ms - TimerId timerId = 0u; - const std::string target = inTask.dstTarget; - RefObject::IncObjRef(this); - errCode = RuntimeContext::GetInstance()->SetTimer(RETRY_INTERVAL, [this, target](TimerId id) { - OnSendable(target); - RefObject::DecObjRef(this); - return -E_END_TIMER; - }, nullptr, timerId); + RetrySendTaskIfNeed(inTask.dstTarget); } if (taskNeedFinalize) { TaskFinalizer(inTask, errCode); @@ -968,5 +964,52 @@ void CommunicatorAggregator::ResetFrameRecordIfNeed(const uint32_t frameId, cons } } +void CommunicatorAggregator::RetrySendTaskIfNeed(const std::string &target) +{ + if (IsRetryOutOfLimit(target)) { + LOGD("[CommAggr] Retry send task is out of limit! target is %s{private}", target.c_str()); + scheduler_.InvalidSendTask(target); + std::lock_guard autoLock(retryCountMutex_); + retryCount_[target] = 0; + } else { + scheduler_.DelayTaskByTarget(target); + RetrySendTask(target); + } +} + +void CommunicatorAggregator::RetrySendTask(const std::string &target) +{ + int32_t currentRetryCount = 0; + { + std::lock_guard autoLock(retryCountMutex_); + retryCount_[target]++; + currentRetryCount = retryCount_[target]; + LOGD("[CommAggr] Target %s{private} retry count is %" PRId32, target.c_str(), currentRetryCount); + } + TimerId timerId = 0u; + RefObject::IncObjRef(this); + (void)RuntimeContext::GetInstance()->SetTimer(GetNextRetryInterval(target, currentRetryCount), + [this, target](TimerId id) { + OnSendable(target); + RefObject::DecObjRef(this); + return -E_END_TIMER; + }, nullptr, timerId); +} + +bool CommunicatorAggregator::IsRetryOutOfLimit(const std::string &target) +{ + std::lock_guard autoLock(retryCountMutex_); + return retryCount_[target] >= MAX_SEND_RETRY; +} + +int32_t CommunicatorAggregator::GetNextRetryInterval(const std::string &target, int32_t currentRetryCount) +{ + uint32_t timeout = DBConstant::MIN_TIMEOUT; + if (adapterHandle_ != nullptr) { + timeout = adapterHandle_->GetTimeout(target); + } + return static_cast(timeout) * currentRetryCount / RETRY_TIME_SPLITS; +} + DEFINE_OBJECT_TAG_FACILITIES(CommunicatorAggregator) } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp index 2b9822b6..cd8928f0 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp @@ -210,10 +210,12 @@ int NetworkAdapter::SendBytes(const std::string &dstTarget, const uint8_t *bytes if (bytes == nullptr || length == 0) { return -E_INVALID_ARGS; } - LOGI("[NAdapt][SendBytes] Enter, to=%s{private}, length=%u", dstTarget.c_str(), length); + LOGI("[NAdapt][SendBytes] Enter, to=%s{private}, length=%u, totalLength=%u", dstTarget.c_str(), length, + totalLength); DeviceInfos dstDevInfo; dstDevInfo.identifier = dstTarget; - DBStatus errCode = processCommunicator_->SendData(dstDevInfo, bytes, length, totalLength); + DBStatus errCode = processCommunicator_->SendData(dstDevInfo, bytes, length, + totalLength > length ? totalLength : length); if (errCode == DBStatus::RATE_LIMIT) { LOGD("[NAdapt][SendBytes] rate limit!"); return -E_WAIT_RETRY; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp index bf36a532..39f39b0c 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp @@ -288,4 +288,19 @@ int SendTaskScheduler::ScheduleNoDelayTask(SendTask &outTask, SendTaskInfo &outT LOGE("[Scheduler][ScheduleNoDelay] INTERNAL ERROR : NO TASK."); return -E_INTERNAL_ERROR; } + +void SendTaskScheduler::InvalidSendTask(const std::string &target) +{ + std::lock_guard overallLockGuard(overallMutex_); + for (const auto &priority : priorityOrder_) { + if (taskCountByPrio_[priority] == 0) { + // No task of this priority + continue; + } + for (auto &sendTask : taskGroupByPrio_[priority][target]) { + sendTask.isValid = false; + LOGI("[Scheduler][InvalidSendTask] invalid frameId=%" PRIu32, sendTask.frameId); + } + } +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/distributeddb.gni b/kv_store/frameworks/libs/distributeddb/distributeddb.gni index 5b96b6d0..c615293c 100644 --- a/kv_store/frameworks/libs/distributeddb/distributeddb.gni +++ b/kv_store/frameworks/libs/distributeddb/distributeddb.gni @@ -17,6 +17,7 @@ distributeddb_path = distributeddb_src = [ "${distributeddb_path}/common/src/auto_launch.cpp", "${distributeddb_path}/common/src/cloud/asset_operation_utils.cpp", + "${distributeddb_path}/common/src/concurrent_adapter.cpp", "${distributeddb_path}/common/src/data_compression.cpp", "${distributeddb_path}/common/src/data_value.cpp", "${distributeddb_path}/common/src/db_common.cpp", diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h index 53b00dd3..506b9998 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_base/grd_type_export.h @@ -66,9 +66,16 @@ typedef enum KvScanMode { KV_SCAN_PREFIX = 0, KV_SCAN_EQUAL_OR_LESS_KEY = 1, KV_SCAN_EQUAL_OR_GREATER_KEY = 2, + KV_SCAN_RANGE = 3, KV_SCAN_BUTT } GRD_KvScanModeE; +typedef struct GRD_FilterOption { + GRD_KvScanModeE mode; + GRD_KVItem begin; + GRD_KVItem end; +} GRD_FilterOptionT; + typedef struct GRD_ResultSet GRD_ResultSet; typedef struct GRD_DB GRD_DB; typedef struct GRD_KVBatch GRD_KVBatchT; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h index 711027d1..584b398a 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/include/grd_kv/grd_kv_api.h @@ -33,6 +33,13 @@ GRD_API int32_t GRD_KVDel(GRD_DB *db, const char *collectionName, const GRD_KVIt GRD_API int32_t GRD_KVScan(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet); +GRD_API int32_t GRD_KVFilter(GRD_DB *db, const char *collectionName, const GRD_FilterOptionT *scanParams, + GRD_ResultSet **resultSet); + +GRD_API int32_t GRD_KVGetSize(GRD_ResultSet *resultSet, uint32_t *keyLen, uint32_t *valueLen); + +GRD_API int32_t GRD_GetItem(GRD_ResultSet *resultSet, void *key, void *value); + GRD_API int32_t GRD_KVFreeItem(GRD_KVItemT *item); GRD_API int32_t GRD_KVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch); diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h index 8846ca22..53893bda 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/grd_api_manager.h @@ -44,6 +44,10 @@ typedef int32_t (*KVGet)(GRD_DB *db, const char *collectionName, const GRD_KVIte typedef int32_t (*KVDel)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key); typedef int32_t (*KVScan)(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet); +typedef int32_t (*KVFilter)(GRD_DB *db, const char *collectionName, const GRD_FilterOptionT *scanParams, + GRD_ResultSet **resultSet); +typedef int32_t (*KVGetSize)(GRD_ResultSet *resultSet, uint32_t *keyLen, uint32_t *valueLen); +typedef int32_t (*GetItem)(GRD_ResultSet *resultSet, void *key, void *value); typedef int32_t (*KVFreeItem)(GRD_KVItemT *item); typedef int32_t (*KVBatchPrepare)(uint16_t itemNum, GRD_KVBatchT **batch); typedef int32_t (*KVBatchPushback)(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, @@ -75,6 +79,9 @@ struct GRD_APIInfo { KVGet KVGetApi = nullptr; KVDel KVDelApi = nullptr; KVScan KVScanApi = nullptr; + KVFilter KVFilterApi = nullptr; + KVGetSize KVGetSizeApi = nullptr; + GetItem GetItemApi = nullptr; KVFreeItem KVFreeItemApi = nullptr; KVBatchPrepare KVBatchPrepareApi = nullptr; KVBatchPushback KVBatchPushbackApi = nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp index 9a308850..fe63bc14 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/grd_api_manager.cpp @@ -59,6 +59,9 @@ void GRD_DBApiInitCommon(GRD_APIInfo &GRD_DBApiInfo) GRD_DBApiInfo.KVGetApi = GRD_KVGetInner; GRD_DBApiInfo.KVDelApi = GRD_KVDelInner; GRD_DBApiInfo.KVScanApi = GRD_KVScanInner; + GRD_DBApiInfo.KVFilterApi = GRD_KVFilterInner; + GRD_DBApiInfo.KVGetSizeApi = GRD_KVGetSizeInner; + GRD_DBApiInfo.GetItemApi = GRD_GetItemInner; GRD_DBApiInfo.KVFreeItemApi = GRD_KVFreeItemInner; GRD_DBApiInfo.KVBatchPrepareApi = GRD_KVBatchPrepareInner; GRD_DBApiInfo.KVBatchPushbackApi = GRD_KVBatchPushbackInner; @@ -92,6 +95,9 @@ void GRD_DBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) GRD_DBApiInfo.KVGetApi = (KVGet)dlsym(g_library, "GRD_KVGet"); GRD_DBApiInfo.KVDelApi = (KVDel)dlsym(g_library, "GRD_KVDel"); GRD_DBApiInfo.KVScanApi = (KVScan)dlsym(g_library, "GRD_KVScan"); + GRD_DBApiInfo.KVFilterApi = (KVFilter)dlsym(g_library, "GRD_KVFilter"); + GRD_DBApiInfo.KVGetSizeApi = (KVGetSize)dlsym(g_library, "GRD_KVGetSize"); + GRD_DBApiInfo.GetItemApi = (GetItem)dlsym(g_library, "GRD_GetItem"); GRD_DBApiInfo.KVFreeItemApi = (KVFreeItem)dlsym(g_library, "GRD_KVFreeItem"); GRD_DBApiInfo.KVBatchPrepareApi = (KVBatchPrepare)dlsym(g_library, "GRD_KVBatchPrepare"); GRD_DBApiInfo.KVBatchPushbackApi = (KVBatchPushback)dlsym(g_library, "GRD_KVBatchPushback"); diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp index 246494c4..d642f8b1 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/src/os_api.cpp @@ -15,7 +15,7 @@ #include "os_api.h" #include -#include +#include #include #include @@ -40,17 +40,17 @@ bool IsPathExist(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 limit is 64K(0x10000). + const unsigned int maxPathLength = PATH_MAX; + if (inOriPath.length() > maxPathLength) { // max limit is 64K(0x10000). GLOGE("[OS_API] OriPath too long."); return -E_INVALID_ARGS; } - char *realPath = new (std::nothrow) char[MAX_PATH_LENGTH + 1]; + char *realPath = new (std::nothrow) char[maxPathLength + 1]; if (realPath == nullptr) { return -E_OUT_OF_MEMORY; } - if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) { + if (memset_s(realPath, maxPathLength + 1, 0, maxPathLength + 1) != EOK) { delete[] realPath; return -E_SECUREC_ERROR; } @@ -61,11 +61,11 @@ int GetRealPath(const std::string &inOriPath, std::string &outRealPath) return -E_SYSTEM_API_FAIL; } #else - if (_fullpath(realPath, inOriPath.c_str(), MAX_PATH_LENGTH) == nullptr) { + if (_fullpath(realPath, inOriPath.c_str(), maxPathLength) == nullptr) { GLOGE("[OS] Realpath error:%d.", errno); delete [] realPath; return -E_SYSTEM_API_FAIL; - } + } #endif outRealPath = std::string(realPath); delete[] realPath; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp index 0fd91cab..020c1795 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp @@ -30,6 +30,10 @@ GRD_API int32_t GRD_DBOpen(const char *dbPath, const char *configStr, uint32_t f if (GRD_DBApiInfo.DBOpenApi == nullptr) { GRD_DBApiInfo = GetApiInfoInstance(); } + if (GRD_DBApiInfo.DBOpenApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DBApiInfo.DBOpenApi(dbPath, configStr, flags, db); } @@ -38,6 +42,10 @@ GRD_API int32_t GRD_DBClose(GRD_DB *db, uint32_t flags) if (GRD_DBApiInfo.DBCloseApi == nullptr) { GRD_DBApiInfo = GetApiInfoInstance(); } + if (GRD_DBApiInfo.DBCloseApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DBApiInfo.DBCloseApi(db, flags); } @@ -46,6 +54,10 @@ GRD_API int32_t GRD_Flush(GRD_DB *db, uint32_t flags) if (GRD_DBApiInfo.FlushApi == nullptr) { GRD_DBApiInfo = GetApiInfoInstance(); } + if (GRD_DBApiInfo.FlushApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DBApiInfo.FlushApi(db, flags); } @@ -54,6 +66,10 @@ GRD_API int32_t GRD_IndexPreload(GRD_DB *db, const char *collectionName) if (GRD_DBApiInfo.IndexPreloadApi == nullptr) { GRD_DBApiInfo = GetApiInfoInstance(); } + if (GRD_DBApiInfo.IndexPreloadApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DBApiInfo.IndexPreloadApi(db, collectionName); } @@ -62,5 +78,9 @@ GRD_API int32_t GRD_CrcCheck(const char *dbFile) if (GRD_DBApiInfo.CrcCheckApi == nullptr) { GRD_DBApiInfo = GetApiInfoInstance(); } + if (GRD_DBApiInfo.CrcCheckApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DBApiInfo.CrcCheckApi(dbFile); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp index e80868ab..7abb5bff 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api_inner.cpp @@ -75,7 +75,7 @@ int32_t GRD_FlushInner(GRD_DB *db, uint32_t flags) int32_t GRD_IndexPreloadInner(GRD_DB *db, const char *collectionName) { - return GRD_OK; // No support; + return GRD_OK; } int32_t GRD_CrcCheckInner(const char *dbFile) diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.h index 54799cf2..966d29fa 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/check_common.h @@ -34,7 +34,6 @@ public: static int CheckDocument(JsonObject &documentObj, bool &isIdExist); static int CheckUpdata(JsonObject &updataObj); static int CheckProjection(JsonObject &projectionObj, std::vector> &path); - static bool checkIsApiInit(); }; using Key = std::vector; using Value = std::vector; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp index ef2dd5ce..accc95d7 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api.cpp @@ -30,6 +30,10 @@ GRD_API int32_t GRD_CreateCollection(GRD_DB *db, const char *collectionName, con if (GRD_DocApiInfo.CreateCollectionApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.CreateCollectionApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.CreateCollectionApi(db, collectionName, optionStr, flags); } @@ -38,6 +42,10 @@ GRD_API int32_t GRD_DropCollection(GRD_DB *db, const char *collectionName, uint3 if (GRD_DocApiInfo.DropCollectionApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.DropCollectionApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.DropCollectionApi(db, collectionName, flags); } @@ -47,6 +55,10 @@ GRD_API int32_t GRD_UpdateDoc(GRD_DB *db, const char *collectionName, const char if (GRD_DocApiInfo.UpdateDocApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.UpdateDocApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.UpdateDocApi(db, collectionName, filter, update, flags); } @@ -56,6 +68,10 @@ GRD_API int32_t GRD_UpsertDoc(GRD_DB *db, const char *collectionName, const char if (GRD_DocApiInfo.UpsertDocApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.UpsertDocApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.UpsertDocApi(db, collectionName, filter, document, flags); } @@ -64,6 +80,10 @@ GRD_API int32_t GRD_InsertDoc(GRD_DB *db, const char *collectionName, const char if (GRD_DocApiInfo.InsertDocApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.InsertDocApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.InsertDocApi(db, collectionName, document, flags); } @@ -72,6 +92,10 @@ GRD_API int32_t GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char if (GRD_DocApiInfo.DeleteDocApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.DeleteDocApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.DeleteDocApi(db, collectionName, filter, flags); } @@ -81,5 +105,9 @@ GRD_API int32_t GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, if (GRD_DocApiInfo.FindDocApi == nullptr) { GRD_DocApiInfo = GetApiInfoInstance(); } + if (GRD_DocApiInfo.FindDocApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_DocApiInfo.FindDocApi(db, collectionName, query, flags, resultSet); } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp index bf076cbc..fe4663b3 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_document_api_inner.cpp @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "grd_document_api_inner.h" #include "check_common.h" #include "grd_api_manager.h" #include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" -#include "grd_document_api_inner.h" #include "grd_resultset_inner.h" #include "grd_type_inner.h" #include "rd_log_print.h" diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp index cbbaccc2..5e905677 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api.cpp @@ -28,6 +28,10 @@ GRD_API int32_t GRD_Next(GRD_ResultSet *resultSet) if (GRD_ResultSetApiInfo.NextApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.NextApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.NextApi(resultSet); } @@ -36,6 +40,10 @@ GRD_API int32_t GRD_GetValue(GRD_ResultSet *resultSet, char **value) if (GRD_ResultSetApiInfo.GetValueApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.GetValueApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.GetValueApi(resultSet, value); } @@ -44,6 +52,10 @@ GRD_API int32_t GRD_FreeValue(char *value) if (GRD_ResultSetApiInfo.FreeValueApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.FreeValueApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.FreeValueApi(value); } @@ -52,6 +64,10 @@ GRD_API int32_t GRD_FreeResultSet(GRD_ResultSet *resultSet) if (GRD_ResultSetApiInfo.FreeResultSetApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.FreeResultSetApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.FreeResultSetApi(resultSet); } @@ -60,6 +76,10 @@ GRD_API int32_t GRD_Prev(GRD_ResultSet *resultSet) if (GRD_ResultSetApiInfo.PrevApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.PrevApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.PrevApi(resultSet); } @@ -68,5 +88,9 @@ GRD_API int32_t GRD_Fetch(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItem if (GRD_ResultSetApiInfo.FetchApi == nullptr) { GRD_ResultSetApiInfo = GetApiInfoInstance(); } + if (GRD_ResultSetApiInfo.FetchApi == nullptr) { + GLOGE("Fail to dlysm RD api symbol"); + return GRD_INNER_ERR; + } return GRD_ResultSetApiInfo.FetchApi(resultSet, key, value); } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp index be9f562b..5b098603 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/document/grd_resultset_api_inner.cpp @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "grd_resultset_api_inner.h" + #include "doc_errno.h" #include "grd_api_manager.h" #include "grd_base/grd_error.h" -#include "grd_resultset_api_inner.h" #include "grd_resultset_inner.h" #include "rd_log_print.h" @@ -67,11 +68,11 @@ int32_t GRD_FreeResultSetInner(GRD_ResultSet *resultSet) int32_t GRD_PrevInner(GRD_ResultSet *resultSet) { - return GRD_NOT_SUPPORT; // No support; + return GRD_NOT_SUPPORT; } int32_t GRD_FetchInner(GRD_ResultSet *resultSet, GRD_KVItemT *key, GRD_KVItemT *value) { - return GRD_NOT_SUPPORT; // No support; + return GRD_NOT_SUPPORT; } } // namespace DocumentDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h index 110a7617..f4e7a83e 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/include/grd_kv_api_inner.h @@ -31,6 +31,13 @@ int32_t GRD_KVDelInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT int32_t GRD_KVScanInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet); +int32_t GRD_KVFilterInner(GRD_DB *db, const char *collectionName, const GRD_FilterOptionT *scanParams, + GRD_ResultSet **resultSet); + +int32_t GRD_KVGetSizeInner(GRD_ResultSet *resultSet, uint32_t *keyLen, uint32_t *valueLen); + +int32_t GRD_GetItemInner(GRD_ResultSet *resultSet, void *key, void *value); + int32_t GRD_KVFreeItemInner(GRD_KVItemT *item); int32_t GRD_KVBatchPrepareInner(uint16_t itemNum, GRD_KVBatchT **batch); diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp index f7a9fdbb..7f441a65 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api.cpp @@ -28,6 +28,9 @@ GRD_API int32_t GRD_KVPut(GRD_DB *db, const char *collectionName, const GRD_KVIt if (GRD_KVApiInfo.KVPutApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVPutApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVPutApi(db, collectionName, key, value); } @@ -36,6 +39,9 @@ GRD_API int32_t GRD_KVGet(GRD_DB *db, const char *collectionName, const GRD_KVIt if (GRD_KVApiInfo.KVGetApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVGetApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVGetApi(db, collectionName, key, value); } @@ -44,6 +50,9 @@ GRD_API int32_t GRD_KVDel(GRD_DB *db, const char *collectionName, const GRD_KVIt if (GRD_KVApiInfo.KVDelApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVDelApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVDelApi(db, collectionName, key); } @@ -53,14 +62,54 @@ GRD_API int32_t GRD_KVScan(GRD_DB *db, const char *collectionName, const GRD_KVI if (GRD_KVApiInfo.KVScanApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVScanApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVScanApi(db, collectionName, key, mode, resultSet); } +GRD_API int32_t GRD_KVFilter(GRD_DB *db, const char *collectionName, const GRD_FilterOptionT *scanParams, + GRD_ResultSet **resultSet) +{ + if (GRD_KVApiInfo.KVFilterApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.KVFilterApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVFilterApi(db, collectionName, scanParams, resultSet); +} + +GRD_API int32_t GRD_KVGetSize(GRD_ResultSet *resultSet, uint32_t *keyLen, uint32_t *valueLen) +{ + if (GRD_KVApiInfo.KVGetSizeApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.KVGetSizeApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.KVGetSizeApi(resultSet, keyLen, valueLen); +} + +GRD_API int32_t GRD_GetItem(GRD_ResultSet *resultSet, void *key, void *value) +{ + if (GRD_KVApiInfo.GetItemApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.GetItemApi == nullptr) { + return GRD_INNER_ERR; + } + return GRD_KVApiInfo.GetItemApi(resultSet, key, value); +} + GRD_API int32_t GRD_KVFreeItem(GRD_KVItemT *item) { if (GRD_KVApiInfo.KVFreeItemApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVFreeItemApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVFreeItemApi(item); } @@ -69,6 +118,9 @@ GRD_API int32_t GRD_KVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch) if (GRD_KVApiInfo.KVBatchPrepareApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVBatchPrepareApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVBatchPrepareApi(itemNum, batch); } @@ -78,6 +130,9 @@ GRD_API int32_t GRD_KVBatchPushback(const void *key, uint32_t keyLen, const void if (GRD_KVApiInfo.KVBatchPushbackApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVBatchPushbackApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVBatchPushbackApi(key, keyLen, data, dataLen, batch); } @@ -86,6 +141,9 @@ GRD_API int32_t GRD_KVBatchPut(GRD_DB *db, const char *collectionName, GRD_KVBat if (GRD_KVApiInfo.KVBatchPutApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVBatchPutApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVBatchPutApi(db, collectionName, batch); } @@ -94,6 +152,9 @@ GRD_API int32_t GRD_KVBatchDel(GRD_DB *db, const char *collectionName, GRD_KVBat if (GRD_KVApiInfo.KVBatchDelApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVBatchDelApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVBatchDelApi(db, collectionName, batch); } @@ -102,5 +163,8 @@ GRD_API int32_t GRD_KVBatchDestroy(GRD_KVBatchT *batch) if (GRD_KVApiInfo.KVBatchDestoryApi == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); } + if (GRD_KVApiInfo.KVBatchDestoryApi == nullptr) { + return GRD_INNER_ERR; + } return GRD_KVApiInfo.KVBatchDestoryApi(batch); } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp index 0837ae5e..d491f828 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/kv/grd_kv_api_inner.cpp @@ -12,62 +12,79 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "grd_kv_api_inner.h" + #include "check_common.h" #include "grd_api_manager.h" #include "grd_base/grd_error.h" -#include "grd_kv_api_inner.h" #include "grd_type_inner.h" #include "rd_log_print.h" namespace DocumentDB { int32_t GRD_KVPutInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVGetInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, const GRD_KVItemT *value) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVDelInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVScanInner(GRD_DB *db, const char *collectionName, const GRD_KVItemT *key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; +} + +int32_t GRD_KVFilterInner(GRD_DB *db, const char *collectionName, const GRD_FilterOptionT *scanParams, + GRD_ResultSet **resultSet) +{ + return GRD_NOT_SUPPORT; +} + +int32_t GRD_KVGetSizeInner(GRD_ResultSet *resultSet, uint32_t *keyLen, uint32_t *valueLen) +{ + return GRD_NOT_SUPPORT; +} + +int32_t GRD_GetItemInner(GRD_ResultSet *resultSet, void *key, void *value) +{ + return GRD_NOT_SUPPORT; } int32_t GRD_KVFreeItemInner(GRD_KVItemT *item) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVBatchPrepareInner(uint16_t itemNum, GRD_KVBatchT **batch) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVBatchPushbackInner(const void *key, uint32_t keyLen, const void *data, uint32_t dataLen, GRD_KVBatchT *batch) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVBatchPutInner(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVBatchDelInner(GRD_DB *db, const char *collectionName, GRD_KVBatchT *batch) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } int32_t GRD_KVBatchDestroyInner(GRD_KVBatchT *batch) { - return GRD_NOT_SUPPORT; // No support. + return GRD_NOT_SUPPORT; } } // namespace DocumentDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp index 7d7ddf00..258e074f 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/document_key.cpp @@ -14,8 +14,8 @@ */ #include "document_key.h" -#include -#include +#include +#include #include "doc_errno.h" #include "rd_log_print.h" diff --git a/kv_store/frameworks/libs/distributeddb/include/query_expression.h b/kv_store/frameworks/libs/distributeddb/include/query_expression.h index 72b6d453..77a9d3e7 100644 --- a/kv_store/frameworks/libs/distributeddb/include/query_expression.h +++ b/kv_store/frameworks/libs/distributeddb/include/query_expression.h @@ -154,6 +154,7 @@ public: void From(const std::string &tableName); int GetExpressionStatus() const; std::vector GetQueryExpressions() const; + int IsRangeValid() const; private: void AssemblyQueryInfo(const QueryObjType queryOperType, const std::string &field, const QueryValueType type, const std::vector &value, bool isNeedFieldPath); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h index 723cfecb..44efd7b0 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud/cloud_store_types.h @@ -43,8 +43,7 @@ enum class AssetOpType { NO_CHANGE = 0, INSERT, DELETE, - UPDATE, - IGNORE // mark it ignore when not handle asset in (download, batchInsert, batchUpdate) + UPDATE }; enum AssetStatus : uint32_t { @@ -137,8 +136,7 @@ struct SqlCondition { }; enum class RecordStatus { - MIGRATING, - MIGRATE_FINISH + WAIT_COMPENSATED_SYNC }; } // namespace DistributedDB #endif // CLOUD_STORE_TYPE_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h index cc386862..59a627c4 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h @@ -95,8 +95,8 @@ public: DB_API virtual DBStatus Pragma(PragmaCmd cmd, PragmaData &pragmaData) = 0; - DB_API virtual DBStatus UpsertData(RecordStatus status, const std::string &tableName, - const std::vector &records) = 0; + DB_API virtual DBStatus UpsertData(const std::string &tableName, const std::vector &records, + RecordStatus status = RecordStatus::WAIT_COMPENSATED_SYNC) = 0; protected: virtual DBStatus RemoveDeviceDataInner(const std::string &device, ClearMode mode) = 0; virtual DBStatus CreateDistributedTableInner(const std::string &tableName, TableSyncType type) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h index bb04ac60..29c15107 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -80,6 +80,8 @@ enum DBStatus { CLOUD_ASSET_SPACE_INSUFFICIENT, // cloud failed to download asset PROPERTY_CHANGED, // reference property changed CLOUD_VERSION_CONFLICT, // cloud failed to update version + CLOUD_RECORD_EXIST_CONFLICT, // this error happen in Download/BatchInsert/BatchUpdate + REMOTE_ASSETS_FAIL, // remove local assets failed }; struct KvStoreConfig { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp index efed7017..adfdd811 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_delegate_manager.cpp @@ -113,7 +113,8 @@ namespace { properties.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode); properties.SetBoolProp(KvDBProperties::LOCAL_ONLY, option.localOnly); properties.SetBoolProp(KvDBProperties::READ_ONLY_MODE, option.rdconfig.readOnly); - properties.SetBoolProp(KvDBProperties::SHARED_MODE, false); + bool sharedMode = (option.storageEngineType == GAUSSDB_RD); + properties.SetBoolProp(KvDBProperties::SHARED_MODE, sharedMode); } bool CheckObserverConflictParam(const KvStoreNbDelegate::Option &option) diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp index a9bdade8..677f40cf 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp @@ -77,6 +77,8 @@ namespace { { -E_CLOUD_ASSET_SPACE_INSUFFICIENT, CLOUD_ASSET_SPACE_INSUFFICIENT }, { -E_TABLE_REFERENCE_CHANGED, PROPERTY_CHANGED }, { -E_CLOUD_VERSION_CONFLICT, CLOUD_VERSION_CONFLICT }, + { -E_CLOUD_RECORD_EXIST_CONFLICT, CLOUD_RECORD_EXIST_CONFLICT }, + { -E_REMOVE_ASSETS_FAILED, REMOTE_ASSETS_FAIL }, }; } diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp index ca7ebcf6..99d06634 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.cpp @@ -899,7 +899,7 @@ DBStatus KvStoreNbDelegateImpl::SubscribeRemoteQuery(const std::vector &records) +DBStatus RelationalStoreDelegateImpl::UpsertData(const std::string &tableName, const std::vector &records, + RecordStatus status) { if (conn_ == nullptr) { LOGE("[RelationalStore Delegate] Invalid connection for operation!"); @@ -446,6 +446,7 @@ DBStatus RelationalStoreDelegateImpl::UpsertData(RecordStatus status, const std: LOGE("[RelationalStore Delegate] Upsert data failed:%d", errCode); return TransferDBErrno(errCode); } + LOGI("[RelationalStore Delegate] Upsert data success"); return OK; } } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h index ca13d51d..527ea646 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h @@ -77,8 +77,8 @@ public: DBStatus Pragma(PragmaCmd cmd, PragmaData &pragmaData) override; - DBStatus UpsertData(RecordStatus status, const std::string &tableName, - const std::vector &records) override; + DBStatus UpsertData(const std::string &tableName, const std::vector &records, + RecordStatus status) override; private: static void OnSyncComplete(const std::map> &devicesStatus, const SyncStatusCallback &onComplete); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index 9e222dab..4a1a217f 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -25,6 +25,7 @@ #include "relational_store_client.h" #include "runtime_context.h" #include "sqlite_utils.h" +#include "concurrent_adapter.h" // using the "sqlite3sym.h" in OHOS #ifndef USE_SQLITE_SYMBOLS @@ -677,7 +678,7 @@ int LogCommitHookCallback(void *data, sqlite3 *db, const char *zDb, int size) auto it = g_clientChangedDataMap.find(hashFileName); if (it != g_clientChangedDataMap.end() && !it->second.tableData.empty()) { ClientChangedData clientChangedData = g_clientChangedDataMap[hashFileName]; - (void)DistributedDB::RuntimeContext::GetInstance()->ScheduleTask([clientObserver, clientChangedData] { + ConcurrentAdapter::ScheduleTask([clientObserver, clientChangedData] { ClientChangedData taskClientChangedData = clientChangedData; clientObserver(taskClientChangedData); }); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h index bfa37c15..c9545343 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h @@ -201,12 +201,30 @@ public: VBucket &assets) override; int SetIAssetLoader(const std::shared_ptr &loader) override; + + int UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records); + + int UpdateRecordFlag(const std::string &tableName, const std::string &gid, bool recordConflict) override; + + int GetCompensatedSyncQuery(std::vector &syncQuery) override; protected: int FillReferenceData(CloudSyncData &syncData); + int GetInfoByPrimaryKeyOrGidInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, + const VBucket &vBucket, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo); + + int PutCloudSyncDataInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, + DownloadData &downloadData); + virtual int GetReferenceGid(const std::string &tableName, const CloudSyncBatch &syncBatch, std::map &referenceGid); + int FillCloudLogAndAssetInner(SQLiteSingleVerRelationalStorageExecutor *handle, OpType opType, + const CloudSyncData &data, bool fillAsset, bool ignoreEmptyGid); + + int UpdateRecordFlagAfterUpload(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, + const CloudSyncBatch &updateData); + static int FillReferenceDataIntoExtend(const std::vector &rowid, const std::map &referenceGid, std::vector &extend); @@ -236,6 +254,22 @@ private: StoreInfo GetStoreInfo() const; bool IsCurrentLogicDelete() const; + + int UpsertDataInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, + const std::vector &records); + + int UpsertDataInTransaction(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, + const std::vector &records); + + int GetCloudTableWithoutShared(std::vector &tables); + + int GetCompensatedSyncQueryInner(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::vector &tables, std::vector &syncQuery); + + int GetSyncQueryByPk(const std::string &tableName, const std::vector &data, + QuerySyncObject &querySyncObject); + + void FillQueryInKeys(const std::string &col, const std::vector &data, size_t valueType, Query &query); // data std::shared_ptr storageEngine_ = nullptr; std::function onSchemaChanged_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h index 970bfd2b..5116bbe1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h @@ -137,6 +137,17 @@ public: { return E_OK; } + + virtual int UpdateRecordFlag([[gnu::unused]] const std::string &tableName, [[gnu::unused]] const std::string &gid, + [[gnu::unused]] bool recordConflict) + { + return E_OK; + } + + virtual int GetCompensatedSyncQuery([[gnu::unused]] std::vector &syncQuery) + { + return E_OK; + } }; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h index 50418751..42151941 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h @@ -116,6 +116,10 @@ public: VBucket &assets); int SetIAssetLoader(const std::shared_ptr &loader); + + int UpdateRecordFlag(const std::string &tableName, const std::string &gid, bool recordConflict); + + int GetCompensatedSyncQuery(std::vector &syncQuery); protected: void Init(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h index e9d34dbf..f78983ef 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h @@ -38,8 +38,11 @@ struct LogInfo { }; enum class LogInfoFlag : uint32_t { + FLAG_CLOUD = 0x0, FLAG_DELETE = 0x1, - FLAG_LOGIC_DELETE = 0x8 + FLAG_LOCAL = 0x2, + FLAG_LOGIC_DELETE = 0x8, + FLAG_WAIT_COMPENSATED_SYNC = 0x10, }; struct RowDataWithLog { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.cpp index a1ce9d27..80391215 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.cpp @@ -369,9 +369,7 @@ uint64_t RdSingleVerNaturalStore::GetAndIncreaseCacheRecordVersion() const int RdSingleVerNaturalStore::CheckIntegrity() const { - KvDBProperties dbProp = GetDbProperties(); - std::string uri = GetDatabasePath(dbProp); - return RdCrcCheck(uri.c_str()); + return -E_NOT_SUPPORT; } int RdSingleVerNaturalStore::GetCompressionAlgo(std::set &algorithmSet) const @@ -405,6 +403,11 @@ void RdSingleVerNaturalStore::WakeUpSyncer() return; } +void RdSingleVerNaturalStore::CommitNotify(int notifyEvent, KvDBCommitNotifyFilterAbleData *data) +{ + GenericKvDB::CommitNotify(notifyEvent, data); +} + void RdSingleVerNaturalStore::InitDataBaseOption(const KvDBProperties &kvDBProp, OpenDbProperties &option) { option.uri = GetDatabasePath(kvDBProp); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.h index dd7f94da..e364e93e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store.h @@ -139,6 +139,8 @@ public: void WakeUpSyncer() override; + void CommitNotify(int notifyEvent, KvDBCommitNotifyFilterAbleData *data) override; + private: int GetAndInitStorageEngine(const KvDBProperties &kvDBProp); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store_connection.cpp index 1e27b1f3..435d6708 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_natural_store_connection.cpp @@ -75,20 +75,20 @@ int RdSingleVerNaturalStoreConnection::GetEntriesInner(bool isGetValue, const IO if (writeHandle_ != nullptr) { LOGD("[RdSingleVerNaturalStoreConnection] Transaction started already."); errCode = writeHandle_->GetEntries(isGetValue, type, keyPrefix, entries); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } RdSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { LOGE("[RdSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } errCode = handle->GetEntries(isGetValue, type, keyPrefix, entries); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -146,7 +146,7 @@ int RdSingleVerNaturalStoreConnection::GetResultSet(const IOption &option, return errCode; } RdSingleVerResultSet *tmpResultSet = new (std::nothrow) RdSingleVerResultSet(naturalStore, - queryParam.beginKey_, queryParam.endKey_, queryParam.kvScanMode_, ResultSetType::QUERY); + queryParam.beginKey, queryParam.endKey, queryParam.kvScanMode); if (tmpResultSet == nullptr) { LOGE("Create single version result set failed."); return -E_OUT_OF_MEMORY; @@ -263,20 +263,26 @@ int RdSingleVerNaturalStoreConnection::Get(const IOption &option, const Key &key if (writeHandle_ != nullptr) { Timestamp recordTimestamp; errCode = writeHandle_->GetKvData(dataType, key, value, recordTimestamp); - DBDfxAdapter::FinishTraceSQL(); + if (errCode != E_OK) { + LOGE("[RdSingleVerStorageExecutor][Get] Cannot get the data %d", errCode); + } + DBDfxAdapter::FinishTracing(); return errCode; } } RdSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } Timestamp timestamp; errCode = handle->GetKvData(dataType, key, value, timestamp); + if (errCode != E_OK) { + LOGE("[RdSingleVerStorageExecutor][Get] Cannot get the data %d", errCode); + } ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -307,20 +313,20 @@ int RdSingleVerNaturalStoreConnection::GetEntriesInner(const IOption &option, co if (writeHandle_ != nullptr) { LOGD("[RdSingleVerNaturalStoreConnection] Transaction started already."); errCode = writeHandle_->GetEntries(queryParam, type, entries); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } RdSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { LOGE("[RdSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } errCode = handle->GetEntries(queryParam, type, entries); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } int RdSingleVerNaturalStoreConnection::GetEntries(const IOption &option, const Query &query, @@ -651,7 +657,7 @@ int RdSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &option, c int errCode = E_OK; if (option.dataType != IOption::SYNC_DATA) { LOGE("LOCAL_DATA TYPE NOT SUPPORT in RD executor"); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return -E_NOT_SUPPORT; } std::lock_guard lock(transactionMutex_); @@ -659,7 +665,7 @@ int RdSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &option, c isAuto = true; errCode = StartTransactionInner(TransactType::IMMEDIATE); if (errCode != E_OK) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } @@ -674,7 +680,7 @@ int RdSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &option, c errCode = (innerCode != E_OK) ? innerCode : errCode; } } - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.cpp index 25971f5b..71697b18 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.cpp @@ -22,19 +22,14 @@ namespace DistributedDB { RdSingleVerResultSet::RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &key) - : type_(ResultSetType::KEYPREFIX), key_(key), kvDB_(kvDB) + : key_(key), kvDB_(kvDB) { kvScanMode_ = KV_SCAN_PREFIX; } RdSingleVerResultSet::RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &beginKey, - const Key &endKey, GRD_KvScanModeE kvScanMode, const ResultSetType &ResultSetType) - : type_(ResultSetType), beginKey_(beginKey), endKey_(endKey), kvScanMode_(kvScanMode), kvDB_(kvDB) -{ - if (!endKey.empty() && !beginKey.empty()) { - isGetValueFromEntry_ = true; - } // Get data from entry_ that stored in resultSet; -} + const Key &endKey, GRD_KvScanModeE kvScanMode) + : beginKey_(beginKey), endKey_(endKey), kvScanMode_(kvScanMode), kvDB_(kvDB) {} RdSingleVerResultSet::~RdSingleVerResultSet() { @@ -55,8 +50,8 @@ int RdSingleVerResultSet::Open(bool isMemDb) if (kvDB_ == nullptr) { // Unlikely return -E_INVALID_ARGS; } - if (type_ != ResultSetType::KEYPREFIX && type_ != ResultSetType::QUERY) { - LOGE("[RdSinResSet] Open result set only support prefix and query mode for now."); + if (kvScanMode_ >= KV_SCAN_BUTT) { + LOGE("[RdSinResSet] Open result scan mode is invalid."); return -E_INVALID_ARGS; } int errCode = E_OK; @@ -70,12 +65,8 @@ int RdSingleVerResultSet::Open(bool isMemDb) errCode = handle_->OpenResultSet(key_, kvScanMode_, &resultSet_); break; } - case KV_SCAN_EQUAL_OR_GREATER_KEY: { - errCode = handle_->OpenResultSet(beginKey_, kvScanMode_, &resultSet_); - break; - } - case KV_SCAN_EQUAL_OR_LESS_KEY: { - errCode = handle_->OpenResultSet(endKey_, kvScanMode_, &resultSet_); + case KV_SCAN_RANGE: { + errCode = handle_->OpenResultSet(beginKey_, endKey_, &resultSet_); break; } default: @@ -137,15 +128,11 @@ int RdSingleVerResultSet::GetCount() const int count = 0; switch (kvScanMode_) { case KV_SCAN_PREFIX: { - errCode = handle_->GetCount(key_, count, kvScanMode_, endKey_); - break; - } - case KV_SCAN_EQUAL_OR_GREATER_KEY: { - errCode = handle_->GetCount(beginKey_, count, kvScanMode_, endKey_); + errCode = handle_->GetCount(key_, count, kvScanMode_); break; } - case KV_SCAN_EQUAL_OR_LESS_KEY: { - errCode = handle_->GetCount(endKey_, count, kvScanMode_, endKey_); + case KV_SCAN_RANGE: { + errCode = handle_->GetCount(beginKey_, endKey_, count, kvScanMode_); break; } default: @@ -236,15 +223,6 @@ int RdSingleVerResultSet::MoveToNext() const endPosition_ = position_ + 1; } } - - if (isGetValueFromEntry_) { - errCode = CmpKeyAndStoreEntry(true); - if (errCode != E_OK) { - endPosition_ = position_; - LOGE("[RdSinResSet] CmpKeyAndStoreEntry failed"); - return errCode; - } - } return errCode; } @@ -275,33 +253,10 @@ int RdSingleVerResultSet::MoveToPrev() const } else { --position_; } - - if (isGetValueFromEntry_) { - errCode = CmpKeyAndStoreEntry(false); - if (errCode != E_OK) { - LOGE("[RdSinResSet] store entry faild"); - return errCode; - } - } } return errCode; } -int RdSingleVerResultSet::CmpKeyAndStoreEntry(bool isCmpKey) const -{ - Entry tmpEntry; - int ret = GetEntry(tmpEntry, false); - if (ret != E_OK) { - return -E_NOT_FOUND; - } - if (isCmpKey && RdSingleVerStorageExecutor::CompareKeyWithEndKey(tmpEntry.key, endKey_)) { - (void)MoveToPrev(); // whether MoveToPrev successfully or not,return NOT_FOUND. - return -E_NOT_FOUND; - } - entry_ = tmpEntry; - return E_OK; -} - int RdSingleVerResultSet::MoveTo(int position) const { int errCode = PreCheckResultSet(); @@ -422,36 +377,10 @@ int RdSingleVerResultSet::GetEntry(Entry &entry) const if (position_ == INIT_POSITION || (position_ == endPosition_ && endPosition_ != INIT_POSITION)) { return -E_NO_SUCH_ENTRY; } - - if (!isGetValueFromEntry_) { - errCode = handle_->GetEntry(resultSet_, entry); - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - LOGE("[RdSinResSet][GetEntry] failed to get entry form result set."); - } - } else { - if (position_ >= endPosition_ && endPosition_ != INIT_POSITION) { - return -E_NOT_FOUND; - } - entry = entry_; - } - return errCode == -E_NOT_FOUND ? -E_NO_SUCH_ENTRY : errCode; -} - -int RdSingleVerResultSet::GetEntry(Entry &entry, bool isGetValueFromEntry) const -{ - int errCode = PreCheckResultSet(); - if (errCode != E_OK) { - return errCode; - } - if (!isGetValueFromEntry) { - errCode = handle_->GetEntry(resultSet_, entry); - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - LOGE("[RdSinResSet][GetEntry] failed to get entry form result set."); - } - } else { - entry = entry_; + errCode = handle_->GetEntry(resultSet_, entry); + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + LOGE("[RdSinResSet][GetEntry] failed to get entry form result set."); } return errCode == -E_NOT_FOUND ? -E_NO_SUCH_ENTRY : errCode; } - } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.h b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.h index 81e637b8..b607fe94 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_result_set.h @@ -25,7 +25,7 @@ class RdSingleVerResultSet : public IKvDBResultSet { public: RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &key); RdSingleVerResultSet(RdSingleVerNaturalStore *kvDB, const Key &beginKey, - const Key &endKey, GRD_KvScanModeE kvScanMode, const ResultSetType &ResultSetType); + const Key &endKey, GRD_KvScanModeE kvScanMode); ~RdSingleVerResultSet() override; // Initialize logic @@ -61,9 +61,6 @@ public: // Get the entry of current position. int GetEntry(Entry &entry) const override; - - int GetEntry(Entry &entry, bool isGetValueFromEntry) const; - private: int PreCheckResultSet() const; @@ -71,8 +68,6 @@ private: int MoveToPrev() const; - int CmpKeyAndStoreEntry(bool isCmpKey = true) const; - mutable std::mutex mutex_; mutable bool isOpen_ = false; @@ -83,9 +78,6 @@ private: mutable bool isMovedBefore_ = false; - // For KeyPrefix Type Or Query Type. - ResultSetType type_ = ResultSetType::KEYPREFIX; - Key key_; Key beginKey_; @@ -94,8 +86,6 @@ private: GRD_KvScanModeE kvScanMode_ = KV_SCAN_PREFIX; - mutable bool isGetValueFromEntry_ = false; - mutable Entry entry_; // Common Pointer For Use, Not Own it, Not Responsible To Release It. diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_engine.cpp index aaefb67a..bd7db7c8 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_engine.cpp @@ -127,24 +127,11 @@ int RdSingleVerStorageEngine::TryToOpenMainDatabase(bool isWrite, GRD_DB *&db) if (!isWrite) { optionTemp.createIfNecessary = false; } - int errCode = E_OK; - bool isNeedUpdateCrcCheck = true; - if (OS::CheckPathExistence(optionTemp.uri)) { - errCode = CrcCheckIfNeed(optionTemp); - if (errCode != E_OK) { - LOGE("crc check failed [%d]", errCode); - return errCode; - } - isNeedUpdateCrcCheck = false; - } - errCode = OpenGrdDb(optionTemp, db); + int errCode = OpenGrdDb(optionTemp, db); if (errCode != E_OK) { LOGE("Failed to open the main database [%d]", errCode); return errCode; } - if (isNeedUpdateCrcCheck) { - crcCheck_ = true; - } // Set the engine state to main status for that the main database is valid. SetEngineState(EngineState::MAINDB); @@ -192,9 +179,6 @@ int RdSingleVerStorageEngine::OpenGrdDb(const OpenDbProperties &option, GRD_DB * if (option.createIfNecessary && !option.readOnly) { flag |= GRD_DB_OPEN_CREATE; } - if (!option.readOnly && (option.isNeedIntegrityCheck || option.isNeedRmCorruptedDb)) { - flag |= GRD_DB_OPEN_CHECK; - } if (option.readOnly) { flag |= GRD_DB_OPEN_SHARED_READ_ONLY; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.cpp index 3632cd34..0c10f353 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.cpp @@ -18,47 +18,34 @@ #include #include "db_common.h" +#include "get_query_info.h" #include "grd_db_api.h" #include "grd_document_api.h" #include "grd_error.h" #include "grd_resultset_api.h" +#include "grd_type_export.h" #include "ikvdb_result_set.h" #include "rd_utils.h" #include "sqlite_single_ver_storage_executor_sql.h" -#include "get_query_info.h" -#include "grd_type_export.h" namespace DistributedDB { int GetQueryParam(const Query &query, QueryParam &queryParam) { QueryExpression queryExpression = GetQueryInfo::GetQueryExpression(query); - std::list queryObjNodes_ = queryExpression.GetQueryExpression(); - if (queryObjNodes_.size() > 1) { // Only Support one query filter. - return -E_INVALID_ARGS; - } - for (const auto &queryObjNode : queryObjNodes_) { - if (queryObjNode.operFlag != QueryObjType::KEY_RANGE) { - return -E_INVALID_ARGS; - } - } - queryParam.beginKey_ = queryExpression.GetBeginKey(); - queryParam.endKey_ = queryExpression.GetEndKey(); - if (queryParam.beginKey_.size() > DBConstant::MAX_KEY_SIZE || - queryParam.endKey_.size() > DBConstant::MAX_KEY_SIZE) { - return -E_INVALID_ARGS; - } - if (!queryParam.beginKey_.empty() || queryParam.endKey_.empty()) { - queryParam.kvScanMode_ = KV_SCAN_EQUAL_OR_GREATER_KEY; - } else { - queryParam.kvScanMode_ = KV_SCAN_EQUAL_OR_LESS_KEY; + int errCode = queryExpression.IsRangeValid(); + if (errCode != E_OK) { + return errCode; } + queryParam.beginKey = queryExpression.GetBeginKey(); + queryParam.endKey = queryExpression.GetEndKey(); + queryParam.kvScanMode = KV_SCAN_RANGE; return E_OK; } int GetQueryParam(const Key &keyPrefix, QueryParam &queryParam) { - queryParam.kvScanMode_ = KV_SCAN_PREFIX; - queryParam.keyPrefix_ = keyPrefix; + queryParam.kvScanMode = KV_SCAN_PREFIX; + queryParam.keyPrefix = keyPrefix; return E_OK; } @@ -72,7 +59,6 @@ RDStorageExecutor::~RDStorageExecutor() int RDStorageExecutor::Reset() { - LOGW("[RdSingleVerStorageExecutor] Not support Reset rd single ver storage executor"); return -E_NOT_SUPPORT; } @@ -110,6 +96,15 @@ int RdSingleVerStorageExecutor::OpenResultSet(const Key &key, GRD_KvScanModeE mo return errCode; } +int RdSingleVerStorageExecutor::OpenResultSet(const Key &beginKey, const Key &endKey, GRD_ResultSet **resultSet) +{ + int errCode = RdKVRangeScan(db_, SYNC_COLLECTION_NAME.c_str(), beginKey, endKey, resultSet); + if (errCode != E_OK) { + LOGE("Can not open rd result set."); + } + return errCode; +} + int RdSingleVerStorageExecutor::CloseResultSet(GRD_ResultSet *resultSet) { int errCode = RdFreeResultSet(resultSet); @@ -147,30 +142,7 @@ int RdSingleVerStorageExecutor::InnerMoveToHead(const int position, GRD_ResultSe return E_OK; } -bool RdSingleVerStorageExecutor::CompareKeyWithEndKey(const Key &key, const Key &keyEnd) -{ - return key > keyEnd; -} - -int RdSingleVerStorageExecutor::CompareKeyAndStoreEntry(GRD_ResultSet *resultSet, const Key &keyEnd, - bool isNeedStore, Entry &entry_) -{ - if (!keyEnd.empty()) { - Entry tmpEntry; - int errCode = RdKvFetch(resultSet, tmpEntry.key, tmpEntry.value); - if (errCode != E_OK || CompareKeyWithEndKey(tmpEntry.key, keyEnd)) { - return -E_NOT_FOUND; - } else { - if (isNeedStore) { - entry_ = tmpEntry; // store the entry. - } - } - } - return E_OK; -} - -int RdSingleVerStorageExecutor::MoveTo(const int position, GRD_ResultSet *resultSet, int &currPosition, - Entry &entry_, const Key &keyEnd) +int RdSingleVerStorageExecutor::MoveTo(const int position, GRD_ResultSet *resultSet, int &currPosition) { int errCode = E_OK; // incase it never been move before if (currPosition == INIT_POSITION) { @@ -210,10 +182,6 @@ int RdSingleVerStorageExecutor::MoveTo(const int position, GRD_ResultSet *result LOGE("[RdSingleVerStorageExecutor] failed to move next for result set."); return errCode; } - errCode = CompareKeyAndStoreEntry(resultSet, keyEnd, true, entry_); - if (errCode != E_OK) { - return -E_NOT_FOUND; // Current Key is bigger than End Key, return no found. - } currPosition++; } return E_OK; @@ -246,17 +214,11 @@ int RdSingleVerStorageExecutor::GetEntry(GRD_ResultSet *resultSet, Entry &entry) return errCode; } -int RdSingleVerStorageExecutor::GetCount(const Key &key, int &count, GRD_KvScanModeE kvScanMode, const Key &keyEnd) +int RdSingleVerStorageExecutor::GetCountInner(GRD_ResultSet *tmpResultSet, int &count) { - count = 0; - GRD_ResultSet *tmpResultSet = nullptr; - int errCode = RdKVScan(db_, SYNC_COLLECTION_NAME.c_str(), key, kvScanMode, &tmpResultSet); - if (errCode != E_OK) { - LOGE("[RdSingleVerStorageExecutor] failed to get count for current key."); - return errCode; - } bool isFirstMove = true; int ret = E_OK; + int errCode = E_OK; while (errCode == E_OK) { errCode = TransferGrdErrno(GRD_Next(tmpResultSet)); if (isFirstMove && errCode == -E_NOT_FOUND) { @@ -275,11 +237,6 @@ int RdSingleVerStorageExecutor::GetCount(const Key &key, int &count, GRD_KvScanM } return errCode; } - Entry entryTmp; - errCode = CompareKeyAndStoreEntry(tmpResultSet, keyEnd, false, entryTmp); - if (errCode != E_OK) { - break; // No need to return errCode when GetCount. - } ++count; isFirstMove = false; } @@ -290,6 +247,30 @@ int RdSingleVerStorageExecutor::GetCount(const Key &key, int &count, GRD_KvScanM return E_OK; } +int RdSingleVerStorageExecutor::GetCount(const Key &key, int &count, GRD_KvScanModeE kvScanMode) +{ + count = 0; + GRD_ResultSet *tmpResultSet = nullptr; + int errCode = RdKVScan(db_, SYNC_COLLECTION_NAME.c_str(), key, kvScanMode, &tmpResultSet); + if (errCode != E_OK) { + LOGE("[RdSingleVerStorageExecutor] failed to get count for current key."); + return errCode; + } + return GetCountInner(tmpResultSet, count); +} + +int RdSingleVerStorageExecutor::GetCount(const Key &beginKey, const Key &endKey, int &count, GRD_KvScanModeE kvScanMode) +{ + count = 0; + GRD_ResultSet *tmpResultSet = nullptr; + int errCode = RdKVRangeScan(db_, SYNC_COLLECTION_NAME.c_str(), beginKey, endKey, &tmpResultSet); + if (errCode != E_OK) { + LOGE("[RdSingleVerStorageExecutor] failed to get count for current key."); + return errCode; + } + return GetCountInner(tmpResultSet, count); +} + int RdSingleVerStorageExecutor::PrepareNotifyForEntries(const std::vector &entries, SingleVerNaturalStoreCommitNotifyData *committedData, std::vector ¬ifys, bool isDelete) @@ -337,19 +318,17 @@ int RdSingleVerStorageExecutor::GetEntriesPrepare(GRD_DB *db, SingleVerDataType return -E_INVALID_ARGS; } int ret = E_OK; - switch (queryParam.kvScanMode_) { - case KV_SCAN_PREFIX: - ret = RdKVScan(db, SYNC_COLLECTION_NAME.c_str(), queryParam.keyPrefix_, KV_SCAN_PREFIX, resultSet); - break; - case KV_SCAN_EQUAL_OR_GREATER_KEY: - ret = RdKVScan(db, SYNC_COLLECTION_NAME.c_str(), queryParam.beginKey_, - KV_SCAN_EQUAL_OR_GREATER_KEY, resultSet); + switch (queryParam.kvScanMode) { + case KV_SCAN_PREFIX: { + ret = RdKVScan(db, SYNC_COLLECTION_NAME.c_str(), queryParam.keyPrefix, KV_SCAN_PREFIX, resultSet); break; - case KV_SCAN_EQUAL_OR_LESS_KEY: - ret = RdKVScan(db, SYNC_COLLECTION_NAME.c_str(), queryParam.endKey_, KV_SCAN_EQUAL_OR_LESS_KEY, resultSet); + } + case KV_SCAN_RANGE: { + ret = RdKVRangeScan(db, SYNC_COLLECTION_NAME.c_str(), queryParam.beginKey, queryParam.endKey, resultSet); break; + } default: - break; + return -E_INVALID_ARGS; } if (ret != E_OK) { LOGE("[RdSingleVerStorageExecutor][GetEntries]ERROR %d", ret); @@ -443,12 +422,6 @@ int RdSingleVerStorageExecutor::GetEntries(QueryParam &queryParam, SingleVerData } return ret; } - if (!queryParam.endKey_.empty() && !queryParam.beginKey_.empty()) { - if (CompareKeyWithEndKey(tmpEntry.key, queryParam.endKey_)) { - ret = -E_NOT_FOUND; - break; - } - } entries.push_back(std::move(tmpEntry)); ret = TransferGrdErrno(GRD_Next(resultSet)); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.h index abe96a13..978fb047 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_single_ver_storage_executor.h @@ -26,10 +26,10 @@ namespace DistributedDB { struct QueryParam { - GRD_KvScanModeE kvScanMode_; - std::vector beginKey_; - std::vector endKey_; - Key keyPrefix_; + GRD_KvScanModeE kvScanMode; + std::vector beginKey; + std::vector endKey; + Key keyPrefix; }; int GetQueryParam(const Query &query, QueryParam &queryParam); @@ -77,7 +77,9 @@ public: int GetEntries(QueryParam &queryParam, SingleVerDataType type, std::vector &entries) const; - int GetCount(const Key &key, int &count, GRD_KvScanModeE kvScanMode, const Key &keyEnd); + int GetCount(const Key &key, int &count, GRD_KvScanModeE kvScanMode); + + int GetCount(const Key &beginKey, const Key &endKey, int &count, GRD_KvScanModeE kvScanMode); // Get all the meta keys. int GetAllMetaKeys(std::vector &keys) const; @@ -115,10 +117,11 @@ public: int OpenResultSet(const Key &key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet); + int OpenResultSet(const Key &beginKey, const Key &endKey, GRD_ResultSet **resultSet); + int CloseResultSet(GRD_ResultSet *resultSet); - int MoveTo(const int position, GRD_ResultSet *resultSet, int &currPosition, - Entry &entry_, const Key &keyEnd); + int MoveTo(const int position, GRD_ResultSet *resultSet, int &currPosition); int MoveToNext(GRD_ResultSet *resultSet); @@ -205,9 +208,6 @@ public: int GetExistsDevicesFromMeta(std::set &devices); int UpdateKey(const UpdateKeyCallback &callback); - - static bool CompareKeyWithEndKey(const Key &key, const Key &keyEnd); - protected: int SaveKvData(SingleVerDataType type, const Key &key, const Value &value); @@ -235,8 +235,7 @@ private: static int GetEntriesPrepare(GRD_DB *db, SingleVerDataType type, const QueryParam &queryParam, std::vector &entries, GRD_ResultSet **resultSet); - int CompareKeyAndStoreEntry(GRD_ResultSet *resultSet, const Key &keyEnd, - bool isNeedStore, Entry &entry_); + int GetCountInner(GRD_ResultSet *tmpResultSet, int &count); }; } // namespace DistributedDB #endif // RD_SINGLE_VER_STORAGE_EXECUTOR_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.cpp index dc5d30e3..5aaccb85 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.cpp @@ -51,7 +51,7 @@ namespace DistributedDB { std::string InitRdConfig() { return R"("pageSize": 32, "redoFlushByTrx": 1, "redoPubBufSize": 2048, "maxConnNum": 100, - "bufferPoolSize": 2048, "crcCheckEnable": 1, "bufferPoolPolicy": "BUF_PRIORITY_INDEX")"; + "bufferPoolSize": 2048, "crcCheckEnable": 0, "bufferPoolPolicy": "BUF_PRIORITY_INDEX")"; } struct GrdErrnoPair { @@ -82,15 +82,6 @@ const GrdErrnoPair GRD_ERRNO_MAP[] = { { GRD_PERMISSION_DENIED, -E_DENIED_SQL }, { GRD_REBUILD_DATABASE, -E_REBUILD_DATABASE}, // rebuild database means ok }; - -GRD_KVItemT BlobToKvItem(const std::vector &blob) -{ - return { - .data = (void *)&blob[0], - .dataLen = (uint32_t)blob.size() - }; -} - int TransferGrdErrno(int err) { if (err > 0) { @@ -128,8 +119,8 @@ int RdKVPut(GRD_DB *db, const char *collectionName, const Key &key, const Value LOGE("[rdUtils][RdKvPut] invalid db"); return -E_INVALID_DB; } - GRD_KVItemT innerKey = BlobToKvItem(key); - GRD_KVItemT innerVal = BlobToKvItem(value); + GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()}; + GRD_KVItemT innerVal{(void *)&value[0], (uint32_t)value.size()}; int ret = TransferGrdErrno(GRD_KVPut(db, collectionName, &innerKey, &innerVal)); if (ret != E_OK) { LOGE("[rdUtils][RdKvPut] ERROR:%d", ret); @@ -143,11 +134,11 @@ int RdKVGet(GRD_DB *db, const char *collectionName, const Key &key, Value &value LOGE("[rdUtils][RdKvGet] invalid db"); return -E_INVALID_DB; } - GRD_KVItemT innerKey = BlobToKvItem(key); + GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()}; GRD_KVItemT innerVal = { 0 }; int ret = TransferGrdErrno(GRD_KVGet(db, collectionName, &innerKey, &innerVal)); if (ret != E_OK) { - LOGI("[rdUtils][GetKvData] Cannot get the data %d", ret); + // log print on caller return ret; } value = KvItemToBlob(innerVal); @@ -161,7 +152,7 @@ int RdKVDel(GRD_DB *db, const char *collectionName, const Key &key) LOGE("[rdUtils][RdKvDel] invalid db"); return -E_INVALID_DB; } - GRD_KVItemT innerKey = BlobToKvItem(key); + GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()}; int ret = TransferGrdErrno(GRD_KVDel(db, collectionName, &innerKey)); if (ret < 0) { LOGE("[rdUtils][RdKvDel] failed:%d", ret); @@ -179,23 +170,35 @@ int RdKVScan(GRD_DB *db, const char *collectionName, const Key &key, GRD_KvScanM if (key.empty()) { return TransferGrdErrno(GRD_KVScan(db, collectionName, NULL, mode, resultSet)); } - GRD_KVItemT innerKey = BlobToKvItem(key); + GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()}; return TransferGrdErrno(GRD_KVScan(db, collectionName, &innerKey, mode, resultSet)); } +int RdKVRangeScan(GRD_DB *db, const char *collectionName, const Key &beginKey, const Key &endKey, + GRD_ResultSet **resultSet) +{ + if (db == nullptr) { + LOGE("[rdUtils][RdKVScan] invalid db"); + return -E_INVALID_DB; + } + GRD_KVItemT beginInnerKey{(void *)&beginKey[0], (uint32_t)beginKey.size()}; + GRD_KVItemT endInnerKey{(void *)&endKey[0], (uint32_t)endKey.size()}; + GRD_FilterOption filterOpt{KV_SCAN_RANGE, beginInnerKey, endInnerKey}; + return TransferGrdErrno(GRD_KVFilter(db, collectionName, &filterOpt, resultSet)); +} + int RdKvFetch(GRD_ResultSet *resultSet, Key &key, Value &value) { - GRD_KVItemT innerKey = { nullptr, 0 }; - GRD_KVItemT innerValue = { nullptr, 0 }; - int errCode = TransferGrdErrno(GRD_Fetch(resultSet, &innerKey, &innerValue)); + uint32_t keyLen; + uint32_t valueLen; + int errCode = TransferGrdErrno(GRD_KVGetSize(resultSet, &keyLen, &valueLen)); if (errCode != E_OK && errCode != -E_NOT_FOUND) { + LOGE("[rdUtils][RdKvFetch] Can not Get value lens size from resultSet"); return errCode; } - key = KvItemToBlob(innerKey); - value = KvItemToBlob(innerValue); - (void)GRD_KVFreeItem(&innerKey); - (void)GRD_KVFreeItem(&innerValue); - return errCode; + key.resize(keyLen); + value.resize(valueLen); + return TransferGrdErrno(GRD_GetItem(resultSet, key.data(), value.data())); } int RdDBClose(GRD_DB *db, uint32_t flags) @@ -215,8 +218,8 @@ int RdKVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch) int RdKVBatchPushback(GRD_KVBatchT *batch, const Key &key, const Value &value) { - GRD_KVItemT innerKey = BlobToKvItem(key); - GRD_KVItemT innerVal = BlobToKvItem(value); + GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()}; + GRD_KVItemT innerVal{(void *)&value[0], (uint32_t)value.size()}; int ret = TransferGrdErrno( GRD_KVBatchPushback(innerKey.data, innerKey.dataLen, innerVal.data, innerVal.dataLen, batch)); if (ret != E_OK) { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.h b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.h index 938094aa..d9ffa0f0 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/gaussdb_rd/rd_utils.h @@ -32,8 +32,6 @@ const std::string SYNC_COLLECTION_NAME = std::string InitRdConfig(); -GRD_KVItemT BlobToKvItem(const std::vector &blob); - int TransferGrdErrno(int err); std::vector KvItemToBlob(GRD_KVItemT &item); @@ -49,6 +47,9 @@ int RdKVDel(GRD_DB *db, const char *collectionName, const Key &key); int RdKVScan(GRD_DB *db, const char *collectionName, const Key &key, GRD_KvScanModeE mode, GRD_ResultSet **resultSet); +int RdKVRangeScan(GRD_DB *db, const char *collectionName, const Key &beginKey, const Key &endKey, + GRD_ResultSet **resultSet); + int RdKvFetch(GRD_ResultSet *resultSet, Key &key, Value &value); int RdFreeResultSet(GRD_ResultSet *resultSet); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 8e8ca9bd..7852b698 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -18,6 +18,7 @@ #include #include "cloud/cloud_db_constant.h" +#include "concurrent_adapter.h" #include "data_compression.h" #include "db_common.h" #include "db_dfx_adapter.h" @@ -27,6 +28,7 @@ #include "relational_sync_data_inserter.h" #include "res_finalizer.h" #include "runtime_context.h" +#include "time_helper.h" namespace DistributedDB { namespace { @@ -549,7 +551,7 @@ int RelationalSyncAbleStorage::SaveSyncDataItems(const QueryObject &object, std: errCode = handle->SaveSyncItems(inserter); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); if (errCode == E_OK) { // dataItems size > 0 now because already check before // all dataItems will write into db now, so need to observer notify here @@ -712,23 +714,29 @@ int RelationalSyncAbleStorage::GetCompressionAlgo(std::set &a int RelationalSyncAbleStorage::RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, const RelationalObserverAction &action) { - std::lock_guard lock(dataChangeDeviceMutex_); - auto it = dataChangeCallbackMap_.find(connectionId); - if (it != dataChangeCallbackMap_.end()) { - if (it->second.find(observer) != it->second.end()) { - LOGE("obsever already registered"); - return -E_ALREADY_SET; - } - if (it->second.size() >= DBConstant::MAX_OBSERVER_COUNT) { - LOGE("The number of relational observers has been over limit"); - return -E_MAX_LIMITS; + int errCode = E_OK; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, connectionId, observer, action, &errCode] () mutable { + ADAPTER_AUTO_LOCK(lock, dataChangeDeviceMutex_); + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + if (it->second.find(observer) != it->second.end()) { + LOGE("obsever already registered"); + errCode = -E_ALREADY_SET; + return; + } + if (it->second.size() >= DBConstant::MAX_OBSERVER_COUNT) { + LOGE("The number of relational observers has been over limit"); + errCode = -E_MAX_LIMITS; + return; + } + it->second[observer] = action; + } else { + dataChangeCallbackMap_[connectionId][observer] = action; } - it->second[observer] = action; - } else { - dataChangeCallbackMap_[connectionId][observer] = action; - } - LOGI("register relational observer ok"); - return E_OK; + LOGI("register relational observer ok"); + }, {}, {&dataChangeCallbackMap_}); + ADAPTER_WAIT(handle); + return errCode; } int RelationalSyncAbleStorage::UnRegisterObserverAction(uint64_t connectionId, const StoreObserver *observer) @@ -737,21 +745,25 @@ int RelationalSyncAbleStorage::UnRegisterObserverAction(uint64_t connectionId, c EraseDataChangeCallback(connectionId); return E_OK; } - std::lock_guard lock(dataChangeDeviceMutex_); - auto it = dataChangeCallbackMap_.find(connectionId); - if (it != dataChangeCallbackMap_.end()) { - auto action = it->second.find(observer); - if (action != it->second.end()) { - it->second.erase(action); - LOGI("unregister relational observer."); - if (it->second.empty()) { - dataChangeCallbackMap_.erase(it); - LOGI("observer for this delegate is zero now"); + int errCode = -E_NOT_FOUND; + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, connectionId, observer, &errCode] () mutable { + ADAPTER_AUTO_LOCK(lock, dataChangeDeviceMutex_); + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + auto action = it->second.find(observer); + if (action != it->second.end()) { + it->second.erase(action); + LOGI("unregister relational observer."); + if (it->second.empty()) { + dataChangeCallbackMap_.erase(it); + LOGI("observer for this delegate is zero now"); + } + errCode = E_OK; } - return E_OK; } - } - return -E_NOT_FOUND; + }, {}, {&dataChangeCallbackMap_}); + ADAPTER_WAIT(handle); + return errCode; } void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceName, @@ -759,26 +771,26 @@ void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceN { IncObjRef(this); int taskErrCode = - RuntimeContext::GetInstance()->ScheduleTask([this, deviceName, changedData, isChangedData] () mutable { - LOGD("begin to trigger relational observer."); - int observerCnt = 0; - std::lock_guard lock(dataChangeDeviceMutex_); - for (const auto &item : dataChangeCallbackMap_) { - for (auto &action : item.second) { - if (action.second == nullptr) { - continue; + ConcurrentAdapter::ScheduleTask([this, deviceName, changedData, isChangedData] () mutable { + LOGD("begin to trigger relational observer."); + int observerCnt = 0; + ADAPTER_AUTO_LOCK(lock, dataChangeDeviceMutex_); + for (const auto &item : dataChangeCallbackMap_) { + for (auto &action : item.second) { + if (action.second == nullptr) { + continue; + } + observerCnt++; + ChangedData observerChangeData = changedData; + if (action.first != nullptr) { + FilterChangeDataByDetailsType(observerChangeData, action.first->GetCallbackDetailsType()); + } + action.second(deviceName, std::move(observerChangeData), isChangedData); } - observerCnt++; - ChangedData observerChangeData = changedData; - if (action.first != nullptr) { - FilterChangeDataByDetailsType(observerChangeData, action.first->GetCallbackDetailsType()); - } - action.second(deviceName, std::move(observerChangeData), isChangedData); } - } - LOGD("relational observer size = %d", observerCnt); - DecObjRef(this); - }); + LOGD("relational observer size = %d", observerCnt); + DecObjRef(this); + }, {&dataChangeCallbackMap_}); if (taskErrCode != E_OK) { LOGE("TriggerObserverAction scheduletask retCode=%d", taskErrCode); DecObjRef(this); @@ -1156,6 +1168,12 @@ int RelationalSyncAbleStorage::GetInfoByPrimaryKeyOrGid(const std::string &table return -E_INVALID_DB; } + return GetInfoByPrimaryKeyOrGidInner(transactionHandle_, tableName, vBucket, dataInfoWithLog, assetInfo); +} + +int RelationalSyncAbleStorage::GetInfoByPrimaryKeyOrGidInner(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::string &tableName, const VBucket &vBucket, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo) +{ TableSchema tableSchema; int errCode = GetCloudTableSchema(tableName, tableSchema); if (errCode != E_OK) { @@ -1163,8 +1181,8 @@ int RelationalSyncAbleStorage::GetInfoByPrimaryKeyOrGid(const std::string &table return errCode; } RelationalSchemaObject localSchema = GetSchemaInfo(); - transactionHandle_->SetLocalSchema(localSchema); - return transactionHandle_->GetInfoByPrimaryKeyOrGid(tableSchema, vBucket, dataInfoWithLog, assetInfo); + handle->SetLocalSchema(localSchema); + return handle->GetInfoByPrimaryKeyOrGid(tableSchema, vBucket, dataInfoWithLog, assetInfo); } int RelationalSyncAbleStorage::PutCloudSyncData(const std::string &tableName, DownloadData &downloadData) @@ -1173,7 +1191,12 @@ int RelationalSyncAbleStorage::PutCloudSyncData(const std::string &tableName, Do LOGE(" the transaction has not been started"); return -E_INVALID_DB; } + return PutCloudSyncDataInner(transactionHandle_, tableName, downloadData); +} +int RelationalSyncAbleStorage::PutCloudSyncDataInner(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::string &tableName, DownloadData &downloadData) +{ TableSchema tableSchema; int errCode = GetCloudTableSchema(tableName, tableSchema); if (errCode != E_OK) { @@ -1181,11 +1204,11 @@ int RelationalSyncAbleStorage::PutCloudSyncData(const std::string &tableName, Do return errCode; } RelationalSchemaObject localSchema = GetSchemaInfo(); - transactionHandle_->SetLocalSchema(localSchema); + handle->SetLocalSchema(localSchema); TrackerTable trackerTable = storageEngine_->GetTrackerSchema().GetTrackerTable(tableName); - transactionHandle_->SetLogicDelete(IsCurrentLogicDelete()); - errCode = transactionHandle_->PutCloudSyncData(tableName, tableSchema, trackerTable, downloadData); - transactionHandle_->SetLogicDelete(false); + handle->SetLogicDelete(IsCurrentLogicDelete()); + errCode = handle->PutCloudSyncData(tableName, tableSchema, trackerTable, downloadData); + handle->SetLogicDelete(false); return errCode; } @@ -1256,12 +1279,7 @@ int RelationalSyncAbleStorage::FillCloudLogAndAsset(const OpType opType, const C if (opType == OpType::UPDATE && data.updData.assets.empty()) { return E_OK; } - TableSchema tableSchema; - int errCode = GetCloudTableSchema(data.tableName, tableSchema); - if (errCode != E_OK) { - LOGE("get table schema failed when fill log and asset. %d", errCode); - return errCode; - } + int errCode = E_OK; auto writeHandle = static_cast( storageEngine_->FindExecutor(true, OperatePerm::NORMAL_PERM, errCode)); if (writeHandle == nullptr) { @@ -1272,7 +1290,7 @@ int RelationalSyncAbleStorage::FillCloudLogAndAsset(const OpType opType, const C ReleaseHandle(writeHandle); return errCode; } - errCode = writeHandle->FillHandleWithOpType(opType, data, fillAsset, ignoreEmptyGid, tableSchema); + errCode = FillCloudLogAndAssetInner(writeHandle, opType, data, fillAsset, ignoreEmptyGid); if (errCode != E_OK) { LOGE("Failed to fill version or cloud asset, opType:%d ret:%d.", opType, errCode); writeHandle->Rollback(); @@ -1300,12 +1318,15 @@ std::string RelationalSyncAbleStorage::GetIdentify() const void RelationalSyncAbleStorage::EraseDataChangeCallback(uint64_t connectionId) { - std::lock_guard lock(dataChangeDeviceMutex_); - auto it = dataChangeCallbackMap_.find(connectionId); - if (it != dataChangeCallbackMap_.end()) { - dataChangeCallbackMap_.erase(it); - LOGI("erase all observer for this delegate."); - } + TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, connectionId] () mutable { + ADAPTER_AUTO_LOCK(lock, dataChangeDeviceMutex_); + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + dataChangeCallbackMap_.erase(it); + LOGI("erase all observer for this delegate."); + } + }, {}, {&dataChangeCallbackMap_}); + ADAPTER_WAIT(handle); } void RelationalSyncAbleStorage::ReleaseContinueToken(ContinueToken &continueStmtToken) const @@ -1625,5 +1646,292 @@ int RelationalSyncAbleStorage::SetIAssetLoader(const std::shared_ptr &records) +{ + int errCode = E_OK; + auto *handle = GetHandle(true, errCode); + if (errCode != E_OK) { + return errCode; + } + handle->SetPutDataMode(SQLiteSingleVerRelationalStorageExecutor::PutDataMode::USER); + handle->SetMarkFlagOption(SQLiteSingleVerRelationalStorageExecutor::MarkFlagOption::SET_WAIT_COMPENSATED_SYNC); + errCode = UpsertDataInner(handle, tableName, records); + handle->SetPutDataMode(SQLiteSingleVerRelationalStorageExecutor::PutDataMode::SYNC); + handle->SetMarkFlagOption(SQLiteSingleVerRelationalStorageExecutor::MarkFlagOption::DEFAULT); + ReleaseHandle(handle); + return errCode; +} + +int RelationalSyncAbleStorage::UpsertDataInner(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::string &tableName, const std::vector &records) +{ + int errCode = E_OK; + errCode = handle->StartTransaction(TransactType::IMMEDIATE); + if (errCode != E_OK) { + return errCode; + } + errCode = UpsertDataInTransaction(handle, tableName, records); + if (errCode == E_OK) { + errCode = handle->Commit(); + if (errCode != E_OK) { + LOGE("[RDBStorageEngine] commit failed %d when upsert data", errCode); + } + } else { + int ret = handle->Rollback(); + if (ret != E_OK) { + LOGW("[RDBStorageEngine] rollback failed %d when upsert data", ret); + } + } + return errCode; +} + +int RelationalSyncAbleStorage::UpsertDataInTransaction(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::string &tableName, const std::vector &records) +{ + TableSchema tableSchema; + int errCode = GetCloudTableSchema(tableName, tableSchema); + if (errCode != E_OK) { + LOGE("Get cloud schema failed when save cloud data, %d", errCode); + return errCode; + } + DownloadData downloadData; + for (const auto &record : records) { + DataInfoWithLog dataInfoWithLog; + VBucket assetInfo; + errCode = GetInfoByPrimaryKeyOrGidInner(handle, tableName, record, dataInfoWithLog, assetInfo); + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + return errCode; + } + VBucket recordCopy = record; + if (errCode == -E_NOT_FOUND || + (dataInfoWithLog.logInfo.flag & static_cast(LogInfoFlag::FLAG_DELETE)) != 0) { + downloadData.opType.push_back(OpType::INSERT); + auto currentTime = TimeHelper::GetSysCurrentTime(); + recordCopy[CloudDbConstant::MODIFY_FIELD] = static_cast(currentTime); + recordCopy[CloudDbConstant::CREATE_FIELD] = static_cast(currentTime); + } else { + downloadData.opType.push_back(OpType::UPDATE); + recordCopy[CloudDbConstant::GID_FIELD] = dataInfoWithLog.logInfo.cloudGid; + recordCopy[CloudDbConstant::MODIFY_FIELD] = static_cast(dataInfoWithLog.logInfo.timestamp); + recordCopy[CloudDbConstant::CREATE_FIELD] = static_cast(dataInfoWithLog.logInfo.wTimestamp); + } + downloadData.existDataKey.push_back(dataInfoWithLog.logInfo.dataKey); + downloadData.data.push_back(std::move(recordCopy)); + } + return PutCloudSyncDataInner(handle, tableName, downloadData); +} + +int RelationalSyncAbleStorage::UpdateRecordFlag(const std::string &tableName, const std::string &gid, + bool recordConflict) +{ + if (transactionHandle_ == nullptr) { + LOGE("[RelationalSyncAbleStorage] the transaction has not been started"); + return -E_INVALID_DB; + } + if (gid.empty()) { + LOGE("[RelationalSyncAbleStorage] gid is empty."); + return -E_INVALID_ARGS; + } + return transactionHandle_->UpdateRecordFlag(tableName, recordConflict, gid); +} + +int RelationalSyncAbleStorage::FillCloudLogAndAssetInner(SQLiteSingleVerRelationalStorageExecutor *handle, + OpType opType, const CloudSyncData &data, bool fillAsset, bool ignoreEmptyGid) +{ + TableSchema tableSchema; + int errCode = GetCloudTableSchema(data.tableName, tableSchema); + if (errCode != E_OK) { + LOGE("get table schema failed when fill log and asset. %d", errCode); + return errCode; + } + errCode = handle->FillHandleWithOpType(opType, data, fillAsset, ignoreEmptyGid, tableSchema); + if (errCode != E_OK) { + return errCode; + } + if (opType == OpType::INSERT) { + errCode = UpdateRecordFlagAfterUpload(handle, data.tableName, data.insData); + } else if (opType == OpType::UPDATE) { + errCode = UpdateRecordFlagAfterUpload(handle, data.tableName, data.updData); + } + return errCode; +} + +int RelationalSyncAbleStorage::UpdateRecordFlagAfterUpload(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::string &tableName, const CloudSyncBatch &updateData) +{ + for (size_t i = 0; i < updateData.extend.size(); ++i) { + const auto &record = updateData.extend[i]; + if (DBCommon::IsRecordError(record)) { + continue; + } + const auto &rowId = updateData.rowid[i]; + int errCode = handle->UpdateRecordFlag(tableName, DBCommon::IsRecordIgnored(record), "", rowId); + if (errCode != E_OK) { + LOGE("[RDBStorage] Update record flag failed in index %zu", i); + return errCode; + } + } + return E_OK; +} + +int RelationalSyncAbleStorage::GetCompensatedSyncQuery(std::vector &syncQuery) +{ + std::vector tables; + int errCode = GetCloudTableWithoutShared(tables); + if (errCode != E_OK) { + return errCode; + } + if (tables.empty()) { + LOGD("[RDBStorage] Table is empty, no need to compensated sync"); + return E_OK; + } + auto *handle = GetHandle(true, errCode); + if (errCode != E_OK) { + return errCode; + } + errCode = GetCompensatedSyncQueryInner(handle, tables, syncQuery); + ReleaseHandle(handle); + return errCode; +} + +int RelationalSyncAbleStorage::GetCloudTableWithoutShared(std::vector &tables) +{ + const auto tableInfos = GetSchemaInfo().GetTables(); + for (const auto &[tableName, info] : tableInfos) { + if (info.GetSharedTableMark()) { + continue; + } + TableSchema schema; + int errCode = GetCloudTableSchema(tableName, schema); + if (errCode == -E_NOT_FOUND) { + continue; + } + if (errCode != E_OK) { + LOGW("[RDBStorage] Get cloud table failed %d", errCode); + return errCode; + } + tables.push_back(schema); + } + return E_OK; +} + +int RelationalSyncAbleStorage::GetCompensatedSyncQueryInner(SQLiteSingleVerRelationalStorageExecutor *handle, + const std::vector &tables, std::vector &syncQuery) +{ + int errCode = E_OK; + errCode = handle->StartTransaction(TransactType::IMMEDIATE); + if (errCode != E_OK) { + return errCode; + } + for (const auto &table : tables) { + std::vector syncDataPk; + errCode = handle->GetWaitCompensatedSyncDataPk(table, syncDataPk); + if (errCode != E_OK) { + LOGE("[RDBStorageEngine] Get wait compensated sync data failed! errCode = %d", errCode); + break; + } + if (syncDataPk.empty()) { + // no data need to compensated sync + continue; + } + QuerySyncObject syncObject; + errCode = GetSyncQueryByPk(table.name, syncDataPk, syncObject); + if (errCode != E_OK) { + LOGW("[RDBStorageEngine] Get compensated sync query happen error, ignore it! errCode = %d", errCode); + errCode = E_OK; + continue; + } + syncQuery.push_back(syncObject); + } + if (errCode == E_OK) { + errCode = handle->Commit(); + if (errCode != E_OK) { + LOGE("[RDBStorageEngine] commit failed %d when get compensated sync query", errCode); + } + } else { + int ret = handle->Rollback(); + if (ret != E_OK) { + LOGW("[RDBStorageEngine] rollback failed %d when get compensated sync query", ret); + } + } + return errCode; +} + +int RelationalSyncAbleStorage::GetSyncQueryByPk(const std::string &tableName, + const std::vector &data, QuerySyncObject &querySyncObject) +{ + std::map dataIndex; + std::map> syncPk; + int ignoreCount = 0; + for (const auto &oneRow : data) { + if (oneRow.size() >= 2u) { // mean this data has more than 2 pk + LOGW("[RDBStorageEngine] Not support compensated sync with composite primary key now"); + return -E_NOT_SUPPORT; + } + for (const auto &[col, value] : oneRow) { + if (dataIndex.find(col) == dataIndex.end()) { + dataIndex[col] = value.index(); + } else if (dataIndex[col] != value.index()) { + ignoreCount++; + continue; + } + syncPk[col].push_back(value); + } + } + LOGD("[RDBStorageEngine] match %zu data for compensated sync, ignore %d", data.size(), ignoreCount); + Query query = Query::Select().From(tableName); + for (const auto &[col, pkList] : syncPk) { + FillQueryInKeys(col, pkList, dataIndex[col], query); + } + auto objectList = QuerySyncObject::GetQuerySyncObject(query); + if (objectList.size() != 1u) { + return -E_INTERNAL_ERROR; + } + querySyncObject = objectList[0]; + return E_OK; +} + +void RelationalSyncAbleStorage::FillQueryInKeys(const std::string &col, const std::vector &data, size_t valueType, + Query &query) +{ + switch (valueType) { + case TYPE_INDEX: { + std::vector pkList; + for (const auto &pk : data) { + pkList.push_back(std::get(pk)); + } + query.In(col, pkList); + break; + } + case TYPE_INDEX: { + std::vector pkList; + for (const auto &pk : data) { + pkList.push_back(std::get(pk)); + } + query.In(col, pkList); + break; + } + case TYPE_INDEX: { + std::vector pkList; + for (const auto &pk : data) { + pkList.push_back(std::get(pk)); + } + query.In(col, pkList); + break; + } + case TYPE_INDEX: { + std::vector pkList; + for (const auto &pk : data) { + pkList.push_back(std::get(pk)); + } + query.In(col, pkList); + break; + } + default: + break; + } +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp index 2af779f5..fa480ab2 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_database_upgrader.cpp @@ -159,23 +159,26 @@ int SqliteRelationalDatabaseUpgrader::UpgradeLogTable(const std::string &logTabl } for (const auto &item : schemaObject.GetTables()) { - std::string addColumnSql; + std::vector addColSqlVec; if (logTableVersion < DBConstant::LOG_TABLE_VERSION_3) { - addColumnSql += "alter table " + DBConstant::RELATIONAL_PREFIX + item.first + - "_log add cloud_gid text after hash_key;"; + addColSqlVec.push_back("alter table " + DBConstant::RELATIONAL_PREFIX + item.first + + "_log add cloud_gid text;"); } if (logTableVersion < DBConstant::LOG_TABLE_VERSION_5) { - addColumnSql += "alter table " + DBConstant::RELATIONAL_PREFIX + item.first + - "_log add extend_field blob after cloud_gid;"; - addColumnSql += "alter table " + DBConstant::RELATIONAL_PREFIX + item.first + - "_log add cursor int after extend_field;"; - addColumnSql += "alter table " + DBConstant::RELATIONAL_PREFIX + item.first + - "_log add version int after cursor;"; + addColSqlVec.push_back("alter table " + DBConstant::RELATIONAL_PREFIX + item.first + + "_log add extend_field blob;"); + addColSqlVec.push_back("alter table " + DBConstant::RELATIONAL_PREFIX + item.first + + "_log add cursor int;"); + addColSqlVec.push_back("alter table " + DBConstant::RELATIONAL_PREFIX + item.first + + "_log add version int;"); } - errCode = SQLiteUtils::ExecuteRawSQL(db_, addColumnSql); - if (errCode != E_OK) { - LOGE("[Relational][UpgradeLogTable] add column failed.", errCode); - return errCode; + for (size_t i = 0; i < addColSqlVec.size(); ++i) { + errCode = SQLiteUtils::ExecuteRawSQL(db_, addColSqlVec[i]); + if (errCode != E_OK) { + LOGE("[Relational][UpgradeLogTable] add column failed. err:%d, index:%u, curVer:%s, maxVer:%s", errCode, + i, logTableVersion.c_str(), DBConstant::LOG_TABLE_VERSION_CURRENT.c_str()); + return errCode; + } } } return E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index ad145273..3b31f015 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -426,7 +426,8 @@ void SQLiteRelationalStore::WakeUpSyncer() syncAbleEngine_->WakeUpSyncer(); } -int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName, TableSyncType syncType) +int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName, TableSyncType syncType, + bool trackerSchemaChanged) { auto mode = static_cast(sqliteStorageEngine_->GetProperties().GetIntProp( RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); @@ -442,7 +443,7 @@ int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName, bool schemaChanged = false; int errCode = sqliteStorageEngine_->CreateDistributedTable(tableName, DBCommon::TransferStringToHex(localIdentity), - schemaChanged, syncType); + schemaChanged, syncType, trackerSchemaChanged); if (errCode != E_OK) { LOGE("Create distributed table failed. %d", errCode); } @@ -934,6 +935,16 @@ int SQLiteRelationalStore::SetCloudDB(const std::shared_ptr &cloudDb) return E_OK; } +void SQLiteRelationalStore::AddFields(const std::vector &newFields, const std::set &equalFields, + std::vector &addFields) +{ + for (const auto &newField : newFields) { + if (equalFields.find(newField.colName) == equalFields.end()) { + addFields.push_back(newField); + } + } +} + bool SQLiteRelationalStore::CheckFields(const std::vector &newFields, const TableInfo &tableInfo, std::vector &addFields) { @@ -941,32 +952,41 @@ bool SQLiteRelationalStore::CheckFields(const std::vector &newFields, con if (newFields.size() < oldFields.size()) { return false; } - for (size_t index = 0; index < newFields.size(); index++) { - if (index >= oldFields.size()) { - addFields.push_back(newFields[index]); - continue; - } - int32_t type = newFields[index].type; - // Field type need to match storage type - if (type >= TYPE_INDEX && type <= TYPE_INDEX) { - type++; // storage type - field type = 1 - } else if (type == TYPE_INDEX) { - type = 1; // storage type is STORAGE_TYPE_NULL - } else if (type >= TYPE_INDEX && type <= TYPE_INDEX) { - type = TYPE_INDEX; // storage type is STORAGE_TYPE_BLOB + std::set equalFields; + for (const auto &oldField : oldFields) { + bool isFieldExist = false; + for (const auto &newField : newFields) { + if (newField.colName != oldField.GetFieldName()) { + continue; + } + isFieldExist = true; + int32_t type = newField.type; + // Field type need to match storage type + // Field type : Nil, int64_t, double, std::string, bool, Bytes, Asset, Assets + // Storage type : NONE, NULL, INTEGER, REAL, TEXT, BLOB + if (type >= TYPE_INDEX && type <= TYPE_INDEX) { + type++; // storage type - field type = 1 + } else if (type == TYPE_INDEX) { + type = static_cast(StorageType::STORAGE_TYPE_NULL); + } else if (type >= TYPE_INDEX && type <= TYPE_INDEX) { + type = static_cast(StorageType::STORAGE_TYPE_BLOB); + } + auto primaryKeyMap = tableInfo.GetPrimaryKey(); + auto it = std::find_if(primaryKeyMap.begin(), primaryKeyMap.end(), + [&newField](const std::map::value_type &pair) { + return pair.second == newField.colName; + }); + if (type != static_cast(oldField.GetStorageType()) || + newField.primary != (it != primaryKeyMap.end()) || newField.nullable == oldField.IsNotNull()) { + return false; + } + equalFields.insert(newField.colName); } - auto primaryKeyMap = tableInfo.GetPrimaryKey(); - auto it = std::find_if(primaryKeyMap.begin(), primaryKeyMap.end(), - [&](const std::map::value_type &pair) { - return pair.second == newFields[index].colName; - }); - if (newFields[index].colName != oldFields[index].GetFieldName() || - type != static_cast(oldFields[index].GetStorageType()) || - newFields[index].primary != (it != primaryKeyMap.end()) || - newFields[index].nullable == oldFields[index].IsNotNull()) { + if (!isFieldExist) { return false; } } + AddFields(newFields, equalFields, addFields); return true; } @@ -1213,7 +1233,7 @@ int SQLiteRelationalStore::SetTrackerTable(const TrackerSchema &trackerSchema) if (errCode != E_OK) { return errCode == -E_IGNORE_DATA ? E_OK : errCode; } - errCode = CreateDistributedTable(trackerSchema.tableName, tableInfo.GetTableSyncType()); + errCode = CreateDistributedTable(trackerSchema.tableName, tableInfo.GetTableSyncType(), true); if (errCode != E_OK) { return errCode; } @@ -1375,11 +1395,67 @@ int SQLiteRelationalStore::Pragma(PragmaCmd cmd, PragmaData &pragmaData) int SQLiteRelationalStore::UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records) { - if (sqliteStorageEngine_ == nullptr) { + if (storageEngine_ == nullptr) { LOGE("[RelationalStore][UpsertData] sqliteStorageEngine was not initialized"); return -E_INVALID_DB; } - return sqliteStorageEngine_ ->UpsertData(status, tableName, records); + int errCode = CheckParamForUpsertData(status, tableName, records); + if (errCode != E_OK) { + return errCode; + } + return storageEngine_->UpsertData(status, tableName, records); +} + +int SQLiteRelationalStore::CheckParamForUpsertData(RecordStatus status, const std::string &tableName, + const std::vector &records) +{ + if (status != RecordStatus::WAIT_COMPENSATED_SYNC) { + LOGE("[RelationalStore][CheckParamForUpsertData] invalid status %" PRId64, static_cast(status)); + return -E_INVALID_ARGS; + } + if (records.empty()) { + LOGE("[RelationalStore][CheckParamForUpsertData] records is empty"); + return -E_INVALID_ARGS; + } + size_t recordSize = records.size(); + if (recordSize > DBConstant::MAX_BATCH_SIZE) { + LOGE("[RelationalStore][CheckParamForUpsertData] records size over limit, size %zu", recordSize); + return -E_MAX_LIMITS; + } + return CheckSchemaForUpsertData(tableName, records); +} + +int SQLiteRelationalStore::CheckSchemaForUpsertData(const std::string &tableName, const std::vector &records) +{ + int errCode = ChkSchema(tableName); + if (errCode != E_OK) { + return errCode; + } + auto schema = storageEngine_->GetSchemaInfo(); + auto table = schema.GetTable(tableName); + if (table.IsNoPkTable()) { + LOGE("[RelationalStore][CheckSchemaForUpsertData] not support table without pk"); + return -E_NOT_SUPPORT; + } + std::set dbPkFields; + for (auto &field : table.GetIdentifyKey()) { + dbPkFields.insert(field); + } + for (const auto &record : records) { + std::set recordPkFields; + for (const auto &item : record) { + if (dbPkFields.find(item.first) == dbPkFields.end()) { + continue; + } + recordPkFields.insert(item.first); + } + if (recordPkFields.size() != dbPkFields.size()) { + LOGE("[RelationalStore][CheckSchemaForUpsertData] pk size not equal param %zu schema %zu", + recordPkFields.size(), dbPkFields.size()); + return -E_INVALID_ARGS; + } + } + return errCode; } } #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h index e10e8a4b..db148a8c 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h @@ -62,7 +62,7 @@ public: return storageEngine_; } - int CreateDistributedTable(const std::string &tableName, TableSyncType syncType); + int CreateDistributedTable(const std::string &tableName, TableSyncType syncType, bool trackerSchemaChanged = false); int RemoveDeviceData(); int RemoveDeviceData(const std::string &device, const std::string &tableName); @@ -156,6 +156,9 @@ private: int InitTrackerSchemaFromMeta(); + void AddFields(const std::vector &newFields, const std::set &equalFields, + std::vector &addFields); + bool CheckFields(const std::vector &newFields, const TableInfo &tableInfo, std::vector &addFields); bool PrepareSharedTable(const DataBaseSchema &schema, std::vector &deleteTableNames, @@ -164,6 +167,10 @@ private: int ExecuteCreateSharedTable(const DataBaseSchema &schema); + int CheckParamForUpsertData(RecordStatus status, const std::string &tableName, const std::vector &records); + + int CheckSchemaForUpsertData(const std::string &tableName, const std::vector &records); + static int ReFillSyncInfoTable(const std::vector &actualTable, CloudSyncer::CloudTaskInfo &info); // use for sync Interactive diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp index 9da2faf4..65537eac 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp @@ -197,7 +197,7 @@ int SaveSyncTableTypeAndDropFlagToMeta(SQLiteSingleVerRelationalStorageExecutor } int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, - const std::string &identity, bool &schemaChanged, TableSyncType syncType) + const std::string &identity, bool &schemaChanged, TableSyncType syncType, bool trackerSchemaChanged) { std::lock_guard lock(schemaMutex_); RelationalSchemaObject schema = schema_; @@ -226,7 +226,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin if (errCode != E_OK) { return errCode; } - if (isUpgraded && schemaChanged) { + if (isUpgraded && (schemaChanged || trackerSchemaChanged)) { // Used for upgrading the stock data of the trackerTable errCode = UpgradeTrackerTableLog(tableName, schema); } @@ -1015,11 +1015,5 @@ std::map SQLiteSingleRelationalStorageEngine::GetTableWeightWi } return res; } - -int SQLiteSingleRelationalStorageEngine::UpsertData([[gnu::unused]] RecordStatus status, - [[gnu::unused]] const std::string &tableName, [[gnu::unused]] const std::vector &records) -{ - return E_OK; -} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h index 92dbc08a..9bcba353 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h @@ -36,7 +36,7 @@ public: RelationalSchemaObject GetSchema() const; int CreateDistributedTable(const std::string &tableName, const std::string &identity, bool &schemaChanged, - TableSyncType syncType); + TableSyncType syncType, bool trackerSchemaChanged); int CleanDistributedDeviceTable(std::vector &missingTables); @@ -60,8 +60,6 @@ public: const std::map &alterTableNames); std::pair, int> CalTableRef(const std::vector &tableNames, const std::map &sharedTableOriginNames); - - int UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records); protected: StorageExecutor *NewSQLiteStorageExecutor(sqlite3 *dbHandle, bool isWrite, bool isMemDb) override; int Upgrade(sqlite3 *db) override; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp index 15cd5f19..ced5b494 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.cpp @@ -83,10 +83,6 @@ SQLiteSingleVerDatabaseUpgrader::~SQLiteSingleVerDatabaseUpgrader() db_ = nullptr; } -// NOTE: 先看upgradeLockFile是否存在,存在就把parentDir目录下的,移动到parentDir/main_db目录下 -// 如果文件锁不存在,那么看dbFilePath-的数据库文件是否存在,如果存在,就 -// GetDbVersion, 先开库获得版本之, 然后如果版本值是0, 就移除原来的。 -// 如果版本值不是0, 就创建文件锁, 再把parentDir目录下的,移动到parentDir/main_db目录下 int SQLiteSingleVerDatabaseUpgrader::TransferDatabasePath(const std::string &parentDir, const OpenDbProperties &option) { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp index 625a5a3a..be554a60 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp @@ -1248,7 +1248,7 @@ int SQLiteSingleVerNaturalStore::SaveSyncItems(const QueryObject &query, std::ve errCode = handle->StartTransaction(TransactType::IMMEDIATE); if (errCode != E_OK) { ReleaseHandle(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } bool isPermitForceWrite = !(GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false)); @@ -1282,7 +1282,7 @@ END: } else { (void)handle->Rollback(); // Keep the error code of the first scene } - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); ReleaseHandle(handle); return errCode; } @@ -1304,7 +1304,7 @@ int SQLiteSingleVerNaturalStore::SaveSyncDataToCacheDB(const QueryObject &query, } else { SetMaxTimestamp(maxTimestamp); } - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); ReleaseHandle(handle); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp index 1c0eefab..953ebc4b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp @@ -105,21 +105,21 @@ int SQLiteSingleVerNaturalStoreConnection::Get(const IOption &option, const Key LOGD("Transaction started already."); Timestamp recordTimestamp; errCode = writeHandle_->GetKvData(dataType, key, value, recordTimestamp); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } Timestamp timestamp; errCode = handle->GetKvData(dataType, key, value, timestamp); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -167,20 +167,20 @@ int SQLiteSingleVerNaturalStoreConnection::GetEntries(const IOption &option, con if (writeHandle_ != nullptr) { LOGD("Transaction started already."); errCode = writeHandle_->GetEntries(queryObj, entries); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } errCode = handle->GetEntries(queryObj, entries); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -216,19 +216,19 @@ int SQLiteSingleVerNaturalStoreConnection::GetCount(const IOption &option, const if (writeHandle_ != nullptr) { LOGD("Transaction started already."); errCode = writeHandle_->GetCount(queryObj, count); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } errCode = handle->GetCount(queryObj, count); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -806,13 +806,13 @@ int SQLiteSingleVerNaturalStoreConnection::PutBatchInner(const IOption &option, isAuto = true; errCode = StartTransactionInner(TransactType::IMMEDIATE); if (errCode != E_OK) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } if ((transactionEntrySize_ + entries.size()) > DBConstant::MAX_TRANSACTION_ENTRY_SIZE) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return -E_MAX_LIMITS; } @@ -833,7 +833,7 @@ int SQLiteSingleVerNaturalStoreConnection::PutBatchInner(const IOption &option, errCode = (innerCode != E_OK) ? innerCode : errCode; } } - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -848,13 +848,13 @@ int SQLiteSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &optio isAuto = true; errCode = StartTransactionInner(TransactType::IMMEDIATE); if (errCode != E_OK) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } if ((transactionEntrySize_ + keys.size()) > DBConstant::MAX_TRANSACTION_ENTRY_SIZE) { - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return -E_MAX_LIMITS; } @@ -875,7 +875,7 @@ int SQLiteSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &optio errCode = (innerCode != E_OK) ? innerCode : errCode; } } - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } @@ -1799,7 +1799,7 @@ int SQLiteSingleVerNaturalStoreConnection::GetEntriesInner(bool isGetValue, cons if (writeHandle_ != nullptr) { LOGD("[SQLiteSingleVerNaturalStoreConnection] Transaction started already."); errCode = writeHandle_->GetEntries(isGetValue, type, keyPrefix, entries); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } } @@ -1807,13 +1807,13 @@ int SQLiteSingleVerNaturalStoreConnection::GetEntriesInner(bool isGetValue, cons SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode); if (handle == nullptr) { LOGE("[SQLiteSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } errCode = handle->GetEntries(isGetValue, type, keyPrefix, entries); ReleaseExecutor(handle); - DBDfxAdapter::FinishTraceSQL(); + DBDfxAdapter::FinishTracing(); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 84ae341c..fc257d9d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -64,7 +64,7 @@ int PermitSelect(void *a, int b, const char *c, const char *d, const char *e, co SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecutor(sqlite3 *dbHandle, bool writable, DistributedTableMode mode) : SQLiteStorageExecutor(dbHandle, writable, false), mode_(mode), isLogicDelete_(false), - assetLoader_(nullptr) + assetLoader_(nullptr), putDataMode_(PutDataMode::SYNC), markFlagOption_(MarkFlagOption::DEFAULT) { bindCloudFieldFuncMap_[TYPE_INDEX] = &CloudStorageUtils::BindInt64; bindCloudFieldFuncMap_[TYPE_INDEX] = &CloudStorageUtils::BindBool; @@ -1953,7 +1953,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogStatement(const TableSc std::string cloudGid; int ret = E_OK; errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); - if (errCode != E_OK) { + if (putDataMode_ == PutDataMode::SYNC && errCode != E_OK) { SQLiteUtils::ResetStatement(selectStmt, true, ret); LOGE("Get cloud gid fail when bind query log statement."); return errCode; @@ -2363,7 +2363,9 @@ int SQLiteSingleVerRelationalStorageExecutor::InsertCloudData(VBucket &vBucket, LOGE("Get insert statement failed when save cloud data, %d", errCode); return errCode; } - CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); + if (putDataMode_ == PutDataMode::SYNC) { + CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); + } errCode = BindValueToUpsertStatement(vBucket, tableSchema.fields, insertStmt); if (errCode != E_OK) { SQLiteUtils::ResetStatement(insertStmt, true, errCode); @@ -2385,7 +2387,7 @@ int SQLiteSingleVerRelationalStorageExecutor::InsertCloudData(VBucket &vBucket, int SQLiteSingleVerRelationalStorageExecutor::InsertLogRecord(const TableSchema &tableSchema, const TrackerTable &trackerTable, VBucket &vBucket) { - if (!CloudStorageUtils::IsContainsPrimaryKey(tableSchema)) { + if (putDataMode_ == PutDataMode::SYNC && !CloudStorageUtils::IsContainsPrimaryKey(tableSchema)) { // when one data is deleted, "insert or replace" will insert another log record if there is no primary key, // so we need to delete the old log record according to the gid first std::string gidStr; @@ -2470,10 +2472,12 @@ int SQLiteSingleVerRelationalStorageExecutor::BindHashKeyAndGidToInsertLogStatem } std::string cloudGid; - errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); - if (errCode != E_OK) { - LOGE("get gid for insert log statement failed, %d", errCode); - return -E_CLOUD_ERROR; + if (putDataMode_ == PutDataMode::SYNC) { + errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); + if (errCode != E_OK) { + LOGE("get gid for insert log statement failed, %d", errCode); + return -E_CLOUD_ERROR; + } } errCode = SQLiteUtils::BindTextToStatement(insertLogStmt, 8, cloudGid); // 8 is cloud_gid @@ -2494,7 +2498,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindHashKeyAndGidToInsertLogStatem } std::string version; - if (tableSchema.sharedTableName.empty()) { + if (putDataMode_ == PutDataMode::SYNC && tableSchema.sharedTableName.empty()) { errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::VERSION_FIELD, vBucket, version); if (errCode != E_OK) { LOGE("get version for insert log statement failed, %d", errCode); @@ -2518,13 +2522,13 @@ int SQLiteSingleVerRelationalStorageExecutor::BindValueToInsertLogStatement(VBuc return errCode; } - errCode = SQLiteUtils::BindTextToStatement(insertLogStmt, 2, "cloud"); // 2 is device + errCode = SQLiteUtils::BindTextToStatement(insertLogStmt, 2, GetDev()); // 2 is device if (errCode != E_OK) { LOGE("Bind device to insert log statement failed, %d", errCode); return errCode; } - errCode = SQLiteUtils::BindTextToStatement(insertLogStmt, 3, "cloud"); // 3 is ori_device + errCode = SQLiteUtils::BindTextToStatement(insertLogStmt, 3, GetDev()); // 3 is ori_device if (errCode != E_OK) { LOGE("Bind ori_device to insert log statement failed, %d", errCode); return errCode; @@ -2555,7 +2559,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindValueToInsertLogStatement(VBuc return errCode; } - errCode = SQLiteUtils::MapSQLiteErrno(sqlite3_bind_int(insertLogStmt, 6, 0)); // 6 is flag + errCode = SQLiteUtils::MapSQLiteErrno(sqlite3_bind_int(insertLogStmt, 6, GetDataFlag())); // 6 is flag if (errCode != E_OK) { LOGE("Bind flag to insert log statement failed, %d", errCode); return errCode; @@ -2586,15 +2590,16 @@ std::string SQLiteSingleVerRelationalStorageExecutor::GetWhereConditionForDataTa return where; } -int SQLiteSingleVerRelationalStorageExecutor::GetUpdateSqlForCloudSync(const TableSchema &tableSchema, - const std::string &gidStr, const std::set &pkSet, std::string &updateSql) +int SQLiteSingleVerRelationalStorageExecutor::GetUpdateSqlForCloudSync(const std::vector &updateFields, + const TableSchema &tableSchema, const std::string &gidStr, const std::set &pkSet, + std::string &updateSql) { if (pkSet.empty() && gidStr.empty()) { LOGE("update data fail because both primary key and gid is empty."); return -E_CLOUD_ERROR; } std::string sql = "UPDATE " + tableSchema.name + " SET"; - for (const auto &field : tableSchema.fields) { + for (const auto &field : updateFields) { sql += " " + field.colName + " = ?,"; } sql.pop_back(); @@ -2626,8 +2631,9 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const } std::set pkSet = CloudStorageUtils::GetCloudPrimaryKey(tableSchema); + auto updateFields = GetUpdateField(vBucket, tableSchema); std::string updateSql; - errCode = GetUpdateSqlForCloudSync(tableSchema, gidStr, pkSet, updateSql); + errCode = GetUpdateSqlForCloudSync(updateFields, tableSchema, gidStr, pkSet, updateSql); if (errCode != E_OK) { return errCode; } @@ -2639,12 +2645,11 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const } // bind value - std::vector fields = tableSchema.fields; if (!pkSet.empty()) { std::vector pkFields = CloudStorageUtils::GetCloudPrimaryKeyField(tableSchema, true); - fields.insert(fields.end(), pkFields.begin(), pkFields.end()); + updateFields.insert(updateFields.end(), pkFields.begin(), pkFields.end()); } - errCode = BindValueToUpsertStatement(vBucket, fields, updateStmt); + errCode = BindValueToUpsertStatement(vBucket, updateFields, updateStmt); if (errCode != E_OK) { LOGE("bind value to update statement failed when update cloud data, %d", errCode); SQLiteUtils::ResetStatement(updateStmt, true, errCode); @@ -2654,7 +2659,9 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudData(VBucket &vBucket, const TableSchema &tableSchema) { - CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); + if (putDataMode_ == PutDataMode::SYNC) { + CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); + } sqlite3_stmt *updateStmt = nullptr; int errCode = GetUpdateDataTableStatement(vBucket, tableSchema, updateStmt); if (errCode != E_OK) { @@ -2702,7 +2709,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateLogRecordStatement(const if (opType == OpType::DELETE) { updateLogSql += GetCloudDeleteSql(DBCommon::GetLogTableName(tableSchema.name)); } else { - updateLogSql += "flag = 0, cloud_gid = ?, "; + updateLogSql += GetUpdateDataFlagSql() + ", cloud_gid = ?, "; updateColName.push_back(CloudDbConstant::GID_FIELD); } updateLogSql += "device = 'cloud', timestamp = ?"; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index 36251647..630e1fe6 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -36,6 +36,14 @@ namespace DistributedDB { class SQLiteSingleVerRelationalStorageExecutor : public SQLiteStorageExecutor { public: + enum class PutDataMode { + SYNC, + USER + }; + enum class MarkFlagOption { + DEFAULT, + SET_WAIT_COMPENSATED_SYNC + }; SQLiteSingleVerRelationalStorageExecutor(sqlite3 *dbHandle, bool writable, DistributedTableMode mode); ~SQLiteSingleVerRelationalStorageExecutor() override = default; @@ -164,6 +172,15 @@ public: int CleanResourceForDroppedTable(const std::string &tableName); int UpgradedLogForExistedData(TableInfo &tableInfo); + + int UpdateRecordFlag(const std::string &tableName, bool recordConflict, const std::string &gid, + int64_t dataKey = DBConstant::DEFAULT_ROW_ID); + + int GetWaitCompensatedSyncDataPk(const TableSchema &table, std::vector &data); + + void SetPutDataMode(PutDataMode mode); + + void SetMarkFlagOption(MarkFlagOption option); private: int DoCleanLogs(const std::vector &tableNameList, const RelationalSchemaObject &localSchema); @@ -271,8 +288,8 @@ private: std::string GetWhereConditionForDataTable(const std::string &gidStr, const std::set &pkSet, const std::string &tableName, bool queryByPk = true); - int GetUpdateSqlForCloudSync(const TableSchema &tableSchema, const std::string &gidStr, - const std::set &pkSet, std::string &updateSql); + int GetUpdateSqlForCloudSync(const std::vector &updateFields, const TableSchema &tableSchema, + const std::string &gidStr, const std::set &pkSet, std::string &updateSql); int GetUpdateDataTableStatement(const VBucket &vBucket, const TableSchema &tableSchema, sqlite3_stmt *&updateStmt); @@ -366,6 +383,20 @@ private: int UpdateAssetId(const std::string &tableName, const Field &field, int64_t dataKey, const VBucket &vBucket); + int64_t GetDataFlag(); + + std::string GetUpdateDataFlagSql(); + + std::string GetDev(); + + std::vector GetUpdateField(const VBucket &vBucket, const TableSchema &tableSchema); + + int GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector fields, int startIndex, VBucket &record); + + static constexpr const char *UPDATE_FLAG_CLOUD = "flag = 0"; + static constexpr const char *UPDATE_FLAG_WAIT_COMPENSATED_SYNC = "flag = flag | 0x10"; + static constexpr const char *FLAG_IS_WAIT_COMPENSATED_SYNC = "flag & 0x10 != 0"; + std::string baseTblName_; TableInfo table_; // Always operating table, user table when get, device table when put. TableSchema tableSchema_; // for cloud table @@ -378,6 +409,9 @@ private: std::atomic isLogicDelete_; std::shared_ptr assetLoader_; + + PutDataMode putDataMode_; + MarkFlagOption markFlagOption_; }; } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp index e4a2dda8..ca3e0563 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp @@ -37,7 +37,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryInfoSql(const std::string } std::string gid; int errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, gid); - if (errCode != E_OK) { + if (putDataMode_ == PutDataMode::SYNC && errCode != E_OK) { LOGE("Get cloud gid fail when query log table."); return errCode; } @@ -152,6 +152,9 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(OpType opT if (data.assets.at(i).empty()) { continue; } + if (DBCommon::IsRecordIgnored(data.extend[i])) { + continue; + } errCode = InitFillUploadAssetStatement(opType, tableSchema, data, i, stmt); if (errCode != E_OK) { if (errCode == -E_NOT_FOUND) { @@ -906,8 +909,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindStmtWithCloudGid(const CloudSy LOGE("[RDBExecutor] Extend not contain gid"); break; } - bool containError = cloudDataResult.insData.extend[i].find(CloudDbConstant::ERROR_FIELD) != - cloudDataResult.insData.extend[i].end(); + bool containError = DBCommon::IsRecordError(cloudDataResult.insData.extend[i]); if (!ignoreEmptyGid && containError) { LOGE("[RDBExecutor] Fill gid back but got error"); errCode = -E_CLOUD_ERROR; @@ -1394,8 +1396,9 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanDownloadChangedAssets( return E_OK; } int ret = assetLoader_->RemoveLocalAssets(toDeleteAssets); - if (ret != E_OK) { + if (ret != OK) { LOGE("remove local assets failed. %d", ret); + return -E_REMOVE_ASSETS_FAILED; } return E_OK; } @@ -1528,5 +1531,167 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateAssetId(const std::string &t } return errCode; } + +void SQLiteSingleVerRelationalStorageExecutor::SetPutDataMode(PutDataMode mode) +{ + putDataMode_ = mode; +} + +void SQLiteSingleVerRelationalStorageExecutor::SetMarkFlagOption(MarkFlagOption option) +{ + markFlagOption_ = option; +} + +int64_t SQLiteSingleVerRelationalStorageExecutor::GetDataFlag() +{ + if (putDataMode_ != PutDataMode::USER) { + return static_cast(LogInfoFlag::FLAG_CLOUD); + } + auto flag = static_cast(LogInfoFlag::FLAG_LOCAL); + if (markFlagOption_ == MarkFlagOption::SET_WAIT_COMPENSATED_SYNC) { + flag |= static_cast(LogInfoFlag::FLAG_WAIT_COMPENSATED_SYNC); + } + return flag; +} + +std::string SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataFlagSql() +{ + if (putDataMode_ == PutDataMode::SYNC) { + return UPDATE_FLAG_CLOUD; + } + if (markFlagOption_ == MarkFlagOption::SET_WAIT_COMPENSATED_SYNC) { + return UPDATE_FLAG_WAIT_COMPENSATED_SYNC; + } + return UPDATE_FLAG_CLOUD; +} + +std::string SQLiteSingleVerRelationalStorageExecutor::GetDev() +{ + return putDataMode_ == PutDataMode::SYNC ? "cloud" : ""; +} + +std::vector SQLiteSingleVerRelationalStorageExecutor::GetUpdateField(const VBucket &vBucket, + const TableSchema &tableSchema) +{ + std::set useFields; + std::vector fields; + if (putDataMode_ == PutDataMode::SYNC) { + for (const auto &field : tableSchema.fields) { + useFields.insert(field.colName); + } + fields = tableSchema.fields; + } else { + for (const auto &field : vBucket) { + if (field.first.empty() || field.first[0] == '#') { + continue; + } + useFields.insert(field.first); + } + for (const auto &field : tableSchema.fields) { + if (useFields.find(field.colName) == useFields.end()) { + continue; + } + fields.push_back(field); + } + } + return fields; +} + +int SQLiteSingleVerRelationalStorageExecutor::UpdateRecordFlag(const std::string &tableName, bool recordConflict, + const std::string &gid, int64_t dataKey) +{ + if (gid.empty() && dataKey == DBConstant::DEFAULT_ROW_ID) { + LOGE("[RDBExecutor] Update record flag failed with invalid args!"); + return -E_INVALID_ARGS; + } + std::string sql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET flag = "; + if (recordConflict) { + sql += "flag | " + std::to_string(static_cast(LogInfoFlag::FLAG_WAIT_COMPENSATED_SYNC)); + } else { + sql += "flag & " + std::to_string(~static_cast(LogInfoFlag::FLAG_WAIT_COMPENSATED_SYNC)); + } + sql += " WHERE "; + if (!gid.empty()) { + sql += " cloud_gid = '" + gid + "'"; + } + if (dataKey != DBConstant::DEFAULT_ROW_ID) { + if (!gid.empty()) { + sql += " OR "; + } + sql += " data_key = '" + std::to_string(dataKey) + "'"; + } + sql += ";"; + int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql); + if (errCode != E_OK) { + LOGE("[RDBExecutor] Update record flag failed! errCode = %d", errCode); + } + return errCode; +} + +int SQLiteSingleVerRelationalStorageExecutor::GetWaitCompensatedSyncDataPk(const TableSchema &table, + std::vector &data) +{ + std::string sql = "SELECT "; + std::vector pkFields; + for (const auto &field : table.fields) { + if (!field.primary) { + continue; + } + sql += "b." + field.colName + ","; + pkFields.push_back(field); + } + if (pkFields.empty()) { + // ignore no pk table + return E_OK; + } + sql.pop_back(); + sql += CloudStorageUtils::GetLeftJoinLogSql(table.name) + " WHERE a." + FLAG_IS_WAIT_COMPENSATED_SYNC; + sqlite3_stmt *stmt = nullptr; + int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); + if (errCode != E_OK) { + LOGE("[RDBExecutor] Get stmt failed when get wait compensated sync pk! errCode = %d", errCode); + return errCode; + } + do { + errCode = SQLiteUtils::StepWithRetry(stmt); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + VBucket pkData; + errCode = GetRecordFromStmt(stmt, pkFields, 0, pkData); + if (errCode != E_OK) { + LOGE("[RDBExecutor] Get record failed when get wait compensated sync pk! errCode = %d", errCode); + break; + } + data.push_back(pkData); + } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + errCode = E_OK; + break; + } else { + LOGE("[RDBExecutor] Step failed when get wait compensated sync pk! errCode = %d", errCode); + break; + } + } while (errCode == E_OK); + int ret = E_OK; + SQLiteUtils::ResetStatement(stmt, true, ret); + return errCode == E_OK ? ret : errCode; +} + +int SQLiteSingleVerRelationalStorageExecutor::GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector fields, + int startIndex, VBucket &record) +{ + int errCode = E_OK; + for (const auto &field : fields) { + Type cloudValue; + errCode = SQLiteRelationalUtils::GetCloudValueByType(stmt, field.type, startIndex, cloudValue); + if (errCode != E_OK) { + break; + } + errCode = PutVBucketByType(record, field, cloudValue); + if (errCode != E_OK) { + break; + } + startIndex++; + } + return errCode; +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp index 881f2565..abf30191 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp @@ -504,4 +504,22 @@ int StorageProxy::SetIAssetLoader(const std::shared_ptr &loader) } return store_->SetIAssetLoader(loader); } + +int StorageProxy::UpdateRecordFlag(const std::string &tableName, const std::string &gid, bool recordConflict) +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return E_INVALID_DB; + } + return store_->UpdateRecordFlag(tableName, gid, recordConflict); +} + +int StorageProxy::GetCompensatedSyncQuery(std::vector &syncQuery) +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return E_INVALID_DB; + } + return store_->GetCompensatedSyncQuery(syncQuery); +} } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp index 09b53016..ee9bc0ca 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp @@ -183,7 +183,7 @@ int CloudDBProxy::Download(const std::string &tableName, const std::string &gid, } DBStatus status = iAssetLoader_->Download(tableName, gid, prefix, assets); if (status != OK) { - LOGE("[CloudDBProxy] download asset failed %d", static_cast(status)); + LOGW("[CloudDBProxy] download asset failed %d", static_cast(status)); } return GetInnerErrorCode(status); } @@ -198,8 +198,9 @@ int CloudDBProxy::RemoveLocalAssets(const std::vector &assets) DBStatus status = iAssetLoader_->RemoveLocalAssets(assets); if (status != OK) { LOGE("[CloudDBProxy] remove local asset failed %d", static_cast(status)); + return -E_REMOVE_ASSETS_FAILED; } - return GetInnerErrorCode(status); + return E_OK; } int CloudDBProxy::InnerAction(const std::shared_ptr &context, @@ -346,6 +347,8 @@ int CloudDBProxy::GetInnerErrorCode(DBStatus status) return -E_CLOUD_ASSET_SPACE_INSUFFICIENT; case CLOUD_VERSION_CONFLICT: return -E_CLOUD_VERSION_CONFLICT; + case CLOUD_RECORD_EXIST_CONFLICT: + return -E_CLOUD_RECORD_EXIST_CONFLICT; default: return -E_CLOUD_ERROR; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp index 4e31d7b9..1203bb87 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp @@ -14,6 +14,7 @@ */ #include "cloud/asset_operation_utils.h" #include "cloud/cloud_db_constant.h" +#include "db_common.h" #include "db_errno.h" #include "log_print.h" #include "cloud/cloud_sync_utils.h" @@ -144,7 +145,8 @@ bool CloudSyncUtils::NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cl // But we won't notify the datum bool isSame = localLogInfo.timestamp == cloudLogInfo.timestamp && EqualInMsLevel(localLogInfo.wTimestamp, cloudLogInfo.wTimestamp) && - localLogInfo.cloudGid == cloudLogInfo.cloudGid; + localLogInfo.cloudGid == cloudLogInfo.cloudGid && + (localLogInfo.flag & static_cast(LogInfoFlag::FLAG_WAIT_COMPENSATED_SYNC)) == 0; return !isSame; } @@ -443,10 +445,13 @@ int CloudSyncUtils::FillAssetIdToAssets(CloudSyncBatch &data) if (data.assets[i].empty()) { continue; } - if (data.extend[i].find(CloudDbConstant::ERROR_FIELD) != data.extend[i].end()) { + if (DBCommon::IsRecordError(data.extend[i])) { errCode = -E_CLOUD_ERROR; continue; } + if (DBCommon::IsRecordIgnored(data.extend[i])) { + continue; + } for (auto &[col, value] : data.assets[i]) { if (!CheckIfContainsInsertAssets(value)) { continue; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp index d525c3df..cd108fa8 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp @@ -445,8 +445,8 @@ std::map CloudSyncer::TagAssetsInSingleRecord(VBucket &cove return res; } -int CloudSyncer::FillCloudAssets( - const std::string &tableName, VBucket &normalAssets, VBucket &failedAssets) +int CloudSyncer::FillCloudAssets(const std::string &tableName, VBucket &normalAssets, + VBucket &failedAssets) { int ret = E_OK; if (normalAssets.size() > 1) { @@ -466,7 +466,7 @@ int CloudSyncer::FillCloudAssets( return E_OK; } -int CloudSyncer::HandleDownloadResult(const std::string &tableName, DownloadCommitList &commitList, +int CloudSyncer::HandleDownloadResult(bool recordConflict, const std::string &tableName, DownloadCommitList &commitList, uint32_t &successCount) { successCount = 0; @@ -475,44 +475,17 @@ int CloudSyncer::HandleDownloadResult(const std::string &tableName, DownloadComm LOGE("[CloudSyncer] start transaction Failed before handle download."); return errCode; } - errCode = storageProxy_->SetLogTriggerStatus(false); + errCode = CommitDownloadAssets(recordConflict, tableName, commitList, successCount); if (errCode != E_OK) { - (void)storageProxy_->Rollback(); - return errCode; - } - for (size_t i = 0; i < commitList.size(); i++) { - std::string gid = std::get<0>(commitList[i]); // 0 means gid is the first element in assetsInfo - // 1 means assetsMap info [colName, assets] is the forth element in downloadList[i] - std::map assetsMap = std::get<1>(commitList[i]); - bool setAllNormal = std::get<2>(commitList[i]); // 2 means whether the download return is E_OK - VBucket normalAssets; - VBucket failedAssets; - normalAssets[CloudDbConstant::GID_FIELD] = gid; - failedAssets[CloudDbConstant::GID_FIELD] = gid; - for (auto &assetKvPair : assetsMap) { - Assets &assets = assetKvPair.second; - if (setAllNormal) { - normalAssets[assetKvPair.first] = std::move(assets); - } else { - failedAssets[assetKvPair.first] = std::move(assets); - } - } - errCode = FillCloudAssets(tableName, normalAssets, failedAssets); - if (errCode != E_OK) { - break; - } - successCount++; - } - errCode = storageProxy_->SetLogTriggerStatus(true); - if (errCode != E_OK) { - LOGE("Set log trigger true failed when handle download.%d", errCode); + LOGE("[CloudSyncer] commit download assets failed %d", errCode); successCount = 0; - storageProxy_->Rollback(); + (void)storageProxy_->Rollback(); return errCode; } errCode = storageProxy_->Commit(); if (errCode != E_OK) { successCount = 0; + LOGE("[CloudSyncer] commit failed %d", errCode); } return errCode; } @@ -550,7 +523,7 @@ int CloudSyncer::CloudDbDownloadAssets(TaskId taskId, InnerProcessInfo &info, co // Process result of each asset commitList.push_back(std::make_tuple(downloadItem.gid, std::move(downloadItem.assets), errorCode == E_OK)); downloadStatus = downloadStatus == E_OK ? errorCode : downloadStatus; - int ret = CommitDownloadResult(info, commitList); + int ret = CommitDownloadResult(downloadItem.recordConflict, info, commitList); if (ret != E_OK) { return ret; } @@ -1742,13 +1715,13 @@ void CloudSyncer::UpdateCloudWaterMark(TaskId taskId, const SyncParam ¶m) } } -int CloudSyncer::CommitDownloadResult(InnerProcessInfo &info, DownloadCommitList &commitList) +int CloudSyncer::CommitDownloadResult(bool recordConflict, InnerProcessInfo &info, DownloadCommitList &commitList) { if (commitList.empty()) { return E_OK; } uint32_t successCount = 0u; - int ret = HandleDownloadResult(info.tableName, commitList, successCount); + int ret = HandleDownloadResult(recordConflict, info.tableName, commitList, successCount); info.downLoadInfo.failCount += (commitList.size() - successCount); info.downLoadInfo.successCount -= (commitList.size() - successCount); if (ret != E_OK) { @@ -1932,6 +1905,10 @@ void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) if (notifier != nullptr) { notifier->NotifyProcess(info, {}, true); } + // generate compensated sync + if (!info.priorityTask) { + GenerateCompensatedSync(); + } } int CloudSyncer::DownloadOneBatch(TaskId taskId, SyncParam ¶m) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h index 022ed2f3..e8c3aace 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h @@ -92,6 +92,7 @@ protected: std::map assets; Key hashKey; std::vector primaryKeyValList; + bool recordConflict = false; }; struct ResumeTaskInfo { TaskContext context; @@ -215,9 +216,11 @@ protected: int TagUploadAssets(CloudSyncData &uploadData); - int FillCloudAssets(const std::string &tableName, VBucket &normalAssets, VBucket &failedAssets); + int FillCloudAssets(const std::string &tableName, VBucket &normalAssets, + VBucket &failedAssets); - int HandleDownloadResult(const std::string &tableName, DownloadCommitList &commitList, uint32_t &successCount); + int HandleDownloadResult(bool recordConflict, const std::string &tableName, DownloadCommitList &commitList, + uint32_t &successCount); int FillDownloadExtend(TaskId taskId, const std::string &tableName, const std::string &cloudWaterMark, VBucket &extend); @@ -246,9 +249,7 @@ protected: int TagStatusByStrategy(bool isExist, SyncParam ¶m, DataInfo &dataInfo, OpType &strategyOpResult); - int CommitDownloadResult(InnerProcessInfo &info, DownloadCommitList &commitList); - - void ClearWithoutData(SyncParam ¶m); + int CommitDownloadResult(bool recordConflict, InnerProcessInfo &info, DownloadCommitList &commitList); void ModifyFieldNameToLower(VBucket &data); @@ -306,15 +307,20 @@ protected: int BatchUpdate(Info &updateInfo, CloudSyncData &uploadData, InnerProcessInfo &innerProcessInfo); - int DownloadAssetsOneByOne(const InnerProcessInfo &info, const DownloadItem &downloadItem, + int DownloadAssetsOneByOne(const InnerProcessInfo &info, DownloadItem &downloadItem, std::map &downloadAssets); int GetDBAssets(bool isSharedTable, const InnerProcessInfo &info, const DownloadItem &downloadItem, VBucket &dbAssets); - int DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProcessInfo &info, const DownloadItem &downloadItem, + int DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProcessInfo &info, DownloadItem &downloadItem, std::map &downloadAssets); + int CommitDownloadAssets(bool recordConflict, const std::string &tableName, DownloadCommitList &commitList, + uint32_t &successCount); + + void GenerateCompensatedSync(); + std::mutex dataLock_; TaskId lastTaskId_; std::list taskQueue_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer_extend.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer_extend.cpp index 3ac43b11..10b331cd 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer_extend.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer_extend.cpp @@ -198,7 +198,7 @@ int CloudSyncer::BatchUpdate(Info &updateInfo, CloudSyncData &uploadData, InnerP return E_OK; } -int CloudSyncer::DownloadAssetsOneByOne(const InnerProcessInfo &info, const DownloadItem &downloadItem, +int CloudSyncer::DownloadAssetsOneByOne(const InnerProcessInfo &info, DownloadItem &downloadItem, std::map &downloadAssets) { bool isSharedTable = false; @@ -253,7 +253,7 @@ int CloudSyncer::GetDBAssets(bool isSharedTable, const InnerProcessInfo &info, c } int CloudSyncer::DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProcessInfo &info, - const DownloadItem &downloadItem, std::map &downloadAssets) + DownloadItem &downloadItem, std::map &downloadAssets) { int errCode = E_OK; for (auto &[col, assets] : downloadAssets) { @@ -275,6 +275,10 @@ int CloudSyncer::DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProc LOGD("[CloudSyncer] skip download asset..."); continue; } + if (tmpCode == -E_CLOUD_RECORD_EXIST_CONFLICT) { + downloadItem.recordConflict = true; + continue; + } errCode = (errCode != E_OK) ? errCode : tmpCode; if (tmpCode == -E_NOT_SET) { break; @@ -290,4 +294,63 @@ int CloudSyncer::DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProc } return errCode; } + +int CloudSyncer::CommitDownloadAssets(bool recordConflict, const std::string &tableName, DownloadCommitList &commitList, + uint32_t &successCount) +{ + int errCode = storageProxy_->SetLogTriggerStatus(false); + if (errCode != E_OK) { + return errCode; + } + for (auto &item : commitList) { + std::string gid = std::get<0>(item); // 0 means gid is the first element in assetsInfo + // 1 means assetsMap info [colName, assets] is the forth element in downloadList[i] + std::map assetsMap = std::get<1>(item); + bool setAllNormal = std::get<2>(item); // 2 means whether the download return is E_OK + VBucket normalAssets; + VBucket failedAssets; + normalAssets[CloudDbConstant::GID_FIELD] = gid; + failedAssets[CloudDbConstant::GID_FIELD] = gid; + VBucket &assets = setAllNormal ? normalAssets : failedAssets; + for (auto &[key, asset] : assetsMap) { + assets[key] = std::move(asset); + } + errCode = FillCloudAssets(tableName, normalAssets, failedAssets); + if (errCode != E_OK) { + return errCode; + } + errCode = storageProxy_->UpdateRecordFlag(tableName, gid, recordConflict); + if (errCode != E_OK) { + return errCode; + } + successCount++; + } + return storageProxy_->SetLogTriggerStatus(true); +} + +void CloudSyncer::GenerateCompensatedSync() +{ + std::vector syncQuery; + int errCode = storageProxy_->GetCompensatedSyncQuery(syncQuery); + if (errCode != E_OK) { + LOGW("[CloudSyncer] Generate compensated sync failed by get query! errCode = %d", errCode); + return; + } + if (syncQuery.empty()) { + LOGD("[CloudSyncer] Not need generate compensated sync"); + return; + } + CloudTaskInfo taskInfo; + taskInfo.priorityTask = true; + taskInfo.timeout = CloudDbConstant::CLOUD_DEFAULT_TIMEOUT; + taskInfo.devices.push_back(CloudDbConstant::DEFAULT_CLOUD_DEV); + taskInfo.callback = nullptr; + taskInfo.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + for (const auto &query : syncQuery) { + taskInfo.table.push_back(query.GetRelationTableName()); + taskInfo.queryList.push_back(query); + } + Sync(taskInfo); + LOGD("[CloudSyncer] Generate compensated sync finished"); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn index a74b95ef..ad4fbcf7 100644 --- a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn @@ -77,7 +77,11 @@ config("module_private_config") { "TRACE_SQLITE_EXECUTE", "SQLITE_ENABLE_DROPTABLE_CALLBACK", "OPENSSL_SUPPRESS_DEPRECATED", + "USE_RD_KERNEL", ] + if (is_ohos) { + defines += [ "USE_FFRT" ] + } } ############################################################################### @@ -125,6 +129,7 @@ ohos_source_set("src_file") { ] external_deps = [ "c_utils:utils", + "ffrt:libffrt", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -159,6 +164,7 @@ template("distributeddb_unittest") { ] external_deps = [ "c_utils:utils", + "ffrt:libffrt", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -702,6 +708,48 @@ distributeddb_unittest("DistributedDBCloudAssetsOperationSyncTest") { sources = [ "unittest/common/storage/cloud/distributeddb_cloud_assets_operation_sync_test.cpp" ] } +############################################################################### +# testcase using rd kernel + +distributeddb_unittest( + "DistributedDBStorageMemoryRdSingleVerNaturalStoreTest") { + sources = [ + "unittest/common/storage/distributeddb_storage_memory_rd_single_ver_naturall_store_test.cpp", + "unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp", + ] +} + +distributeddb_unittest("DistributedDBStorageRdRegisterObserverTest") { + sources = [ "unittest/common/storage/distributeddb_storage_rd_register_observer_test.cpp" ] +} + +distributeddb_unittest("DistributedDBStorageRdResultAndJsonOptimizeTest") { + sources = [ "unittest/common/storage/distributeddb_storage_rd_resultset_and_json_optimize.cpp" ] +} + +distributeddb_unittest("DistributedDBStorageRdSingleVerNaturalExecutorTest") { + sources = [ "unittest/common/storage/distributeddb_storage_rd_single_ver_natural_executor_test.cpp" ] +} + +distributeddb_unittest("DistributedDBStorageRdSingleVerNaturalStoreTest") { + sources = [ + "unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_test.cpp", + "unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp", + ] +} + +distributeddb_unittest("DistributedDBStorageRdSingleVerStorageEngineTest") { + sources = [ "unittest/common/storage/distributeddb_storage_rd_single_ver_storage_engine_test.cpp" ] +} + +distributeddb_unittest("DistributedDBInterfacesNBDelegateRdTest") { + sources = [ "unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test_rd_kernal.cpp" ] +} + +distributeddb_unittest("DistributedDBInterfacesDatabaseRdKernelTest") { + sources = [ "unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp" ] +} + ############################################################################### group("unittest") { testonly = true @@ -812,10 +860,22 @@ group("unittest") { ":DistributedInterfacesRelationalTest", ":RuntimeContextProcessSystemApiAdapterImplTest", ] + + if (defined(global_parts_info.distributeddatamgr_kv_store_lite)) { + deps += [ + ":DistributedDBInterfacesDatabaseRdKernelTest", + ":DistributedDBInterfacesNBDelegateRdTest", + ":DistributedDBStorageMemoryRdSingleVerNaturalStoreTest", + ":DistributedDBStorageRdRegisterObserverTest", + ":DistributedDBStorageRdResultAndJsonOptimizeTest", + ":DistributedDBStorageRdSingleVerNaturalExecutorTest", + ":DistributedDBStorageRdSingleVerNaturalStoreTest", + ":DistributedDBStorageRdSingleVerStorageEngineTest", + ] + } } ############################################################################### - group("distributeddatamgr_fuzztest") { testonly = true deps = [] diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp index 6b25ba33..3c6443e0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp @@ -1235,20 +1235,21 @@ END: } void RelationalTestUtils::CloudBlockSync(const DistributedDB::Query &query, - DistributedDB::RelationalStoreDelegate *delegate, DistributedDB::DBStatus expect) + DistributedDB::RelationalStoreDelegate *delegate, DistributedDB::DBStatus expect, + DistributedDB::DBStatus callbackExpect) { ASSERT_NE(delegate, nullptr); std::mutex dataMutex; std::condition_variable cv; bool finish = false; - auto callback = [expect, &cv, &dataMutex, &finish](const std::map &process) { + auto callback = [callbackExpect, &cv, &dataMutex, &finish](const std::map &process) { for (const auto &item: process) { if (item.second.process == DistributedDB::FINISHED) { { std::lock_guard autoLock(dataMutex); finish = true; } - EXPECT_EQ(item.second.errCode, expect); + EXPECT_EQ(item.second.errCode, callbackExpect); cv.notify_one(); } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h index f3d11185..69694814 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h @@ -336,7 +336,8 @@ public: static int GetMetaData(sqlite3 *db, const DistributedDB::Key &key, DistributedDB::Value &value); static int SetMetaData(sqlite3 *db, const DistributedDB::Key &key, const DistributedDB::Value &value); static void CloudBlockSync(const DistributedDB::Query &query, DistributedDB::RelationalStoreDelegate *delegate, - DistributedDB::DBStatus expect = DistributedDB::DBStatus::OK); + DistributedDB::DBStatus expect = DistributedDB::DBStatus::OK, + DistributedDB::DBStatus callbackExpect = DistributedDB::DBStatus::OK); static int SelectData(sqlite3 *db, const DistributedDB::TableSchema &schema, std::vector &data); static DistributedDB::Assets GetAssets(const DistributedDB::Type &value, diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp index 5335a87e..cd378ec0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp @@ -16,6 +16,7 @@ #include #include +#include "concurrent_adapter.h" #include "db_common.h" #include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_unit_test.h" @@ -1044,4 +1045,128 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DropDeleteData001, TestS CheckLogicDeleteData(db, tableName, cursor - num); EXPECT_EQ(sqlite3_close_v2(db), E_OK); } + +/** + * @tc.name: FfrtTest001 + * @tc.desc: Test ffrt concurrency + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest001, TestSize.Level0) +{ + std::map ans; + std::mutex mutex; + size_t num = 1000; + + /** + * @tc.steps:step1. submit insert map task + * @tc.expected: step1. return ok. + */ + TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t j = 0; j < num; j++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (size_t i = 0; i < num; i++) { + ans.insert_or_assign(i, i); + } + } + }, {}, {&ans}); + + /** + * @tc.steps:step2. submit erase map task + * @tc.expected: step2. return ok. + */ + TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t i = 0; i < num; i++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (auto it = ans.begin(); it != ans.end();) { + it = ans.erase(it); + } + } + }, {}, {&ans}); + + /** + * @tc.steps:step3. submit get from map task + * @tc.expected: step3. return ok. + */ + TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t i = 0; i < num; i++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (auto it = ans.begin(); it != ans.end(); it++) { + int j = it->first; + EXPECT_GE(j, 0); + } + } + }, {&ans}, {}); + ADAPTER_WAIT(h1); + ADAPTER_WAIT(h2); + ADAPTER_WAIT(h3); + ASSERT_TRUE(ans.empty()); +} + +/** + * @tc.name: FfrtTest002 + * @tc.desc: Test ffrt concurrency + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Level0) +{ + std::map ans; + std::mutex mutex; + size_t num = 1000; + + /** + * @tc.steps:step1. subtask submit insert map task + * @tc.expected: step1. return ok. + */ + TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + TaskHandle hh1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t j = 0; j < num; j++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (size_t i = 0; i < num; i++) { + ans.insert_or_assign(i, i); + } + } + }, {}, {&ans}); + ADAPTER_WAIT(hh1); + }); + + /** + * @tc.steps:step2. subtask submit erase map task + * @tc.expected: step2. return ok. + */ + TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + TaskHandle hh2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t i = 0; i < num; i++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (auto it = ans.begin(); it != ans.end();) { + it = ans.erase(it); + } + } + }, {}, {&ans}); + ADAPTER_WAIT(hh2); + }); + + /** + * @tc.steps:step3. subtask submit get from map task + * @tc.expected: step3. return ok. + */ + TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + TaskHandle hh3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() { + for (size_t i = 0; i < num; i++) { + ADAPTER_AUTO_LOCK(lock, mutex); + for (auto it = ans.begin(); it != ans.end(); it++) { + int j = it->first; + EXPECT_GE(j, 0); + } + } + }, {&ans}, {}); + ADAPTER_WAIT(hh3); + }); + ADAPTER_WAIT(h1); + ADAPTER_WAIT(h2); + ADAPTER_WAIT(h3); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_set_cloud_schema_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_set_cloud_schema_test.cpp index 3d6271bc..87713eee 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_set_cloud_schema_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_set_cloud_schema_test.cpp @@ -95,8 +95,8 @@ namespace { const std::vector g_cloudField3 = { {"id", TYPE_INDEX, true}, {"name", TYPE_INDEX}, {"height", TYPE_INDEX}, {"married", TYPE_INDEX}, - {"photo", TYPE_INDEX}, {"asset", TYPE_INDEX}, - {"age", TYPE_INDEX} + {"photo", TYPE_INDEX}, {"age", TYPE_INDEX}, + {"asset", TYPE_INDEX} }; const std::vector g_cloudField4 = { {"id", TYPE_INDEX, true}, {"name", TYPE_INDEX}, diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp index e2d00999..d80a9e20 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp @@ -177,6 +177,9 @@ HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore003, TestSize.Le ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); EXPECT_TRUE(g_kvDelegateStatus == OK); + string retStoreId = g_kvNbDelegatePtr->GetStoreId(); + EXPECT_TRUE(retStoreId.compare("distributed_getkvstore_003") == 0); + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); EXPECT_EQ(g_mgr.CloseKvStore(kvNbDelegatePtr1), OK); g_kvNbDelegatePtr = nullptr; @@ -448,34 +451,6 @@ HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore010, TestSize.Le ASSERT_TRUE(g_kvNbDelegatePtr == nullptr); } -/** - * @tc.name: GetKvStore012 - * @tc.desc: Get kv store parameters and call CheckIntegity - * @tc.type: FUNC - * @tc.require: - * @tc.author: zhuwentao - */ -HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore012, TestSize.Level1) -{ - /** - * @tc.steps: step1. open db and readOnly is false - * @tc.expected: step1. open ok - */ - KvStoreNbDelegate::Option option; - option.storageEngineType = GAUSSDB_RD; - option.rdconfig.readOnly = false; - g_mgr.GetKvStore("distributed_getkvstore_012", option, g_kvNbDelegateCallback); - EXPECT_TRUE(g_kvDelegateStatus == OK); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - - /** - * @tc.steps: step2. check db and write db handle close - * @tc.expected: step2. close ok - */ - EXPECT_TRUE(g_kvNbDelegatePtr->CheckIntegrity() == OK); - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); -} - /** * @tc.name: GetKvStore013 * @tc.desc: Get kv store parameters in readOnly mode and RmCorruptedDb is true diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test_rd_kernal.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test_rd_kernal.cpp index b02c52b3..2b2915f8 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test_rd_kernal.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test_rd_kernal.cpp @@ -25,9 +25,7 @@ #include "platform_specific.h" #include "process_system_api_adapter_impl.h" #include "runtime_context.h" -#ifdef DB_DEBUG_ENV #include "system_time.h" -#endif // DB_DEBUG_ENV #include "virtual_communicator_aggregator.h" using namespace testing::ext; @@ -1613,7 +1611,6 @@ HWTEST_F(DistributedDBInterfacesNBDelegateRdTest, GetKeys001, TestSize.Level1) g_kvNbDelegatePtr = nullptr; } -#ifdef DB_DEBUG_ENV /** * @tc.name: TimeChangeWithCloseStoreTest001 * @tc.desc: Test close store with time changed @@ -2284,6 +2281,5 @@ HWTEST_F(DistributedDBInterfacesNBDelegateRdTest, RdRangeQuery005, TestSize.Leve EXPECT_EQ(g_kvNbDelegatePtr->CloseResultSet(resultSet), OK); } } -#endif // DB_DEBUG_ENV } #endif // USE_RD_KERNEL diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp index b08b923b..76b218d5 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp @@ -866,6 +866,17 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest015, */ TrackerSchema schema = g_normalSchema1; EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK); + string querySql = "select extend_field from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + + " where data_key = 15;"; + sqlite3_stmt *stmt = nullptr; + EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK); + while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + std::string extendVal; + EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK); + EXPECT_EQ(extendVal, "Local4"); + } + int errCode; + SQLiteUtils::ResetStatement(stmt, true, errCode); /** * @tc.steps:step4. operator data diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_assets_operation_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_assets_operation_sync_test.cpp index 8d645907..b3042bbe 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_assets_operation_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_assets_operation_sync_test.cpp @@ -193,6 +193,7 @@ void DistributedDBCloudAssetsOperationSyncTest::InsertUserTableRecord(const std: RuntimeContext::GetInstance()->AssetToBlob(asset, assetBlob); std::vector assets; asset.name = name + "_1"; + asset.status = static_cast(AssetStatus::INSERT); assets.push_back(asset); asset.name = name + "_2"; assets.push_back(asset); @@ -264,6 +265,10 @@ void DistributedDBCloudAssetsOperationSyncTest::CheckAssetsCount(const std::vect auto assets = RelationalTestUtils::GetAssets(colValue, translate); LOGI("[DistributedDBCloudAssetsOperationSyncTest] Check data index %d", index); EXPECT_EQ(assets.size(), expectCount[index]); + for (const auto &item : assets) { + LOGI("[DistributedDBCloudAssetsOperationSyncTest] Asset name %s status %" PRIu32, item.name.c_str(), + item.status); + } index++; } } @@ -327,9 +332,10 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation002, T virtualAssetLoader_->ForkRemoveLocalAssets([&removeCount](const std::vector &assets) { EXPECT_EQ(assets.size(), 2u); removeCount++; + return OK; }); UpdateCloudTableRecord(0, actualCount, false); - BlockSync(query, delegate_); + RelationalTestUtils::CloudBlockSync(query, delegate_); EXPECT_EQ(downLoadCount, 3); // local asset was removed should download 3 times EXPECT_EQ(removeCount, 1); virtualAssetLoader_->ForkDownload(nullptr); @@ -383,5 +389,73 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation003, T int errCode; SQLiteUtils::ResetStatement(stmt, true, errCode); } + +/** + * @tc.name: IgnoreRecord001 + * @tc.desc: Download Assets When local assets was removed + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, IgnoreRecord001, TestSize.Level0) +{ + const int actualCount = 1; + InsertUserTableRecord(tableName_, 0, actualCount, 10, false); + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + std::vector expectCount = { 2 }; + CheckAssetsCount(expectCount); + + VBucket record; + record["id"] = std::to_string(0); + record["assets"] = Assets(); + EXPECT_EQ(delegate_->UpsertData(tableName_, { record }), OK); + record["id"] = std::to_string(1); + EXPECT_EQ(delegate_->UpsertData(tableName_, { record }), OK); + expectCount = { 0, 0 }; + CheckAssetsCount(expectCount); +} + +/** + * @tc.name: IgnoreRecord002 + * @tc.desc: Ignore Assets When Download + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, IgnoreRecord002, TestSize.Level0) +{ + const int actualCount = 1; + InsertUserTableRecord(tableName_, 0, actualCount, 10, false); + Query query = Query::Select().FromTable({ tableName_ }); + RelationalTestUtils::CloudBlockSync(query, delegate_); + UpdateCloudTableRecord(0, actualCount, false); + + virtualAssetLoader_->SetDownloadStatus(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + RelationalTestUtils::CloudBlockSync(query, delegate_); + virtualAssetLoader_->SetDownloadStatus(DBStatus::OK); + std::vector expectCount = { 2 }; + CheckAssetsCount(expectCount); + RelationalTestUtils::CloudBlockSync(query, delegate_); +} + +/** + * @tc.name: IgnoreRecord003 + * @tc.desc: Ignore Assets When Upload + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, IgnoreRecord003, TestSize.Level0) +{ + const int actualCount = 1; + InsertUserTableRecord(tableName_, 0, actualCount, 10, false); + Query query = Query::Select().FromTable({ tableName_ }); + virtualCloudDb_->SetConflictInUpload(true); + RelationalTestUtils::CloudBlockSync(query, delegate_); + virtualCloudDb_->SetConflictInUpload(false); + std::vector expectCount = { 2 }; + CheckAssetsCount(expectCount); +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_register_observer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_register_observer_test.cpp index 0c329d5e..edbd9dcb 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_register_observer_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_register_observer_test.cpp @@ -36,7 +36,6 @@ namespace { RdSingleVerNaturalStore *g_singleVerNaturaStore = nullptr; IKvDBConnection *g_singleVerNaturaStoreConnection = nullptr; bool g_createFactory = false; - const int OBSERVER_SLEEP_TIME = 80; Key g_emptyKey; string g_keyStr1 = "key_1"; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_executor_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_executor_test.cpp index 89a84dec..91aa008c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_executor_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_executor_test.cpp @@ -39,11 +39,6 @@ namespace { RdSingleVerNaturalStoreConnection *g_connection = nullptr; RdSingleVerStorageExecutor *g_handle = nullptr; RdSingleVerStorageExecutor *g_nullHandle = nullptr; - - const char * const ADD_SYNC = "ALTER TABLE sync_data ADD column version INT"; - const char * const ADD_LOCAL = "ALTER TABLE local_data ADD column flag INT"; - const char * const INSERT_SQL = "INSERT INTO sync_data VALUES('a', 'b', 1, 2, '', '', 'efdef', 100 , 1);"; - const int SQL_STATE_ERR = -1; } class DistributedDBStorageRdSingleVerNaturalExecutorTest : public testing::Test { diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp index d36fb1c4..fd2adadd 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_natural_store_testcase.cpp @@ -25,15 +25,6 @@ using namespace DistributedDBUnitTest; namespace { const int MAX_TEST_KEY_SIZE = 1024; // 1K const int MAX_TEST_VAL_SIZE = 4194304; // 4M - - // select result index for the item for sync database - const int SYNC_RES_KEY_INDEX = 0; - const int SYNC_RES_VAL_INDEX = 1; - const int SYNC_RES_TIME_INDEX = 2; - const int SYNC_RES_FLAG_INDEX = 3; - const int SYNC_RES_HASH_KEY_INDEX = 6; - - const std::string SYNC_DATA_DEFAULT_SQL = "select * from SYNC_DATA;"; } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_storage_engine_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_storage_engine_test.cpp index fff42fd5..db7d9418 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_storage_engine_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_single_ver_storage_engine_test.cpp @@ -33,10 +33,6 @@ namespace { RdSingleVerNaturalStore *g_store = nullptr; RdSingleVerNaturalStoreConnection *g_connection = nullptr; - const char * const ADD_SYNC = "ALTER TABLE sync_data ADD column version INT"; - const char * const INSERT_SQL = "INSERT INTO sync_data VALUES('a', 'b', 1, 2, '', '', 'efdef', 100 , 1);"; - const int SQL_STATE_ERR = -1; - void GetStorageEngine(RdSingleVerStorageEngine *&storageEngine) { int errCode; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp index b0e404af..b85731bb 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_assets_test.cpp @@ -384,7 +384,6 @@ void DistributedDBCloudSyncerDownloadAssetsTest::CheckLocalAssetIsEmpty(const st std::string sql = "SELECT asset FROM " + tableName + ";"; sqlite3_stmt *stmt = nullptr; ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); - int index = 0; while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_NULL); } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp index 2f29ce4a..10e656a1 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp @@ -41,7 +41,7 @@ DBStatus VirtualAssetLoader::Download(const std::string &tableName, const std::s DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::vector &assets) { if (removeAssetsCallBack_) { - removeAssetsCallBack_(assets); + return removeAssetsCallBack_(assets); } return DBStatus::OK; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h index 5e03934d..1dbd8d89 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h @@ -20,7 +20,7 @@ namespace DistributedDB { using DownloadCallBack = std::function &assets)>; -using RemoveAssetsCallBack = std::function &assets)>; +using RemoveAssetsCallBack = std::function &assets)>; class VirtualAssetLoader : public IAssetLoader { public: VirtualAssetLoader() = default; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp index e2f5a19d..041a697e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp @@ -74,6 +74,9 @@ DBStatus VirtualCloudDb::InnerBatchInsert(const std::string &tableName, std::vec LOGE("[VirtualCloudDb] Insert data should not have gid"); return DB_ERROR; } + if (conflictInUpload_) { + extend[i][CloudDbConstant::ERROR_FIELD] = static_cast(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + } extend[i][g_gidField] = std::to_string(currentGid_++); extend[i][g_cursorField] = std::to_string(currentCursor_++); extend[i][g_deleteField] = false; @@ -380,6 +383,9 @@ DBStatus VirtualCloudDb::InnerUpdateWithoutLock(const std::string &tableName, st LOGE("[VirtualCloudDb] Update data should have gid"); return DB_ERROR; } + if (conflictInUpload_) { + extend[i][CloudDbConstant::ERROR_FIELD] = static_cast(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + } extend[i][g_cursorField] = std::to_string(currentCursor_++); extend[i][CloudDbConstant::VERSION_FIELD] = std::to_string(currentVersion_++); AddAssetIdForExtend(record[i], extend[i]); @@ -565,4 +571,9 @@ void VirtualCloudDb::AddAssetIdForExtend(VBucket &record, VBucket &extend) extend[recordData.first] = assets; } } + +void VirtualCloudDb::SetConflictInUpload(bool conflict) +{ + conflictInUpload_ = conflict; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h index a72d8816..d0ce4b74 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h @@ -82,6 +82,8 @@ public: void SetClearExtend(int32_t count); void SetCloudNetworkError(bool cloudNetworkError); + + void SetConflictInUpload(bool conflict); private: struct CloudData { VBucket record; @@ -116,6 +118,7 @@ private: std::atomic cloudNetworkError_ = false; std::atomic heartbeatError_ = false; std::atomic lockStatus_ = false; + std::atomic conflictInUpload_ = false; std::atomic blockTimeMs_ = 0; std::atomic currentGid_ = 0; std::atomic currentCursor_ = 1; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp index 207e1469..c6069eef 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_subscribe_sync_test.cpp @@ -1212,4 +1212,29 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync014, TestSize. EXPECT_LE(curTime - lastTime, PUT_LIMIT_30S); } LOGD("END PUT"); +} + +/** + * @tc.name: subscribeSync015 + * @tc.desc: test subscribe query with range + * @tc.type: FUNC + * @tc.require: DTS2023112110763 + * @tc.author: mazhao + */ +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync015, TestSize.Level1) +{ + /** + * @tc.steps: step1. InitSchemaDb + */ + LOGI("============step 1============"); + InitSubSchemaDb(); + std::vector devices = {"DEVICE_B"}; + + /** + * @tc.steps: step2. deviceA subscribe query by Range. + * * @tc.expected: step2. interface return not support + */ + Query query = Query::Select().Range({}, {}); + EXPECT_EQ(g_schemaKvDelegatePtr->SubscribeRemoteQuery(devices, nullptr, query, true), NOT_SUPPORT); + EXPECT_EQ(g_schemaKvDelegatePtr->UnSubscribeRemoteQuery(devices, nullptr, query, true), NOT_SUPPORT); } \ No newline at end of file diff --git a/kv_store/interfaces/innerkits/distributeddata/include/executor.h b/kv_store/interfaces/innerkits/distributeddata/include/executor.h index e6bf0f10..3d2c49bc 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/executor.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/executor.h @@ -54,7 +54,7 @@ public: Executor() : thread_([this] { - pthread_setname_np(pthread_self(), "TaskExecutor"); + pthread_setname_np(pthread_self(), "OS_TaskExecutor"); Run(); self_ = nullptr; }) diff --git a/mock/CMakeLists.txt b/mock/CMakeLists.txt index 34d362fe..24dce372 100644 --- a/mock/CMakeLists.txt +++ b/mock/CMakeLists.txt @@ -26,7 +26,7 @@ set(MOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}) include(${CMAKE_CURRENT_SOURCE_DIR}/include/CMakeLists.txt OPTIONAL) set(links secure crypto) -add_library(mock SHARED ${mockSrc}) +add_library(mock SHARED ${mockSrc} src/mock_dfs_service.cpp) target_link_libraries(mock ${links}) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/) @@ -236,6 +236,8 @@ target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/nap target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/napi/native_engine) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/filemanagement/file_api/interfaces/kits) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include) +target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/filemanagement/dfs_service/interfaces/inner_api/native/cloudsync_kit_inner) +target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/innerkits/filemanagement/dfs_service/frameworks/native/cloudsync_kit_inner/include) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability/ability_runtime) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability) diff --git a/mock/src/mock_dfs_service.cpp b/mock/src/mock_dfs_service.cpp index 9b9c765d..fdffc984 100644 --- a/mock/src/mock_dfs_service.cpp +++ b/mock/src/mock_dfs_service.cpp @@ -1,4 +1,34 @@ -// -// Created by 86131 on 2023/12/13. -// +#include "cloud_sync_asset_manager.h" +#include "cloud_sync_asset_manager_impl.h" +namespace OHOS::FileManagement::CloudSync { + +CloudSyncAssetManager& CloudSyncAssetManager::GetInstance() +{ + return CloudSyncAssetManagerImpl::GetInstance(); +} + +CloudSyncAssetManagerImpl& CloudSync::CloudSyncAssetManagerImpl::GetInstance() +{ + static CloudSyncAssetManagerImpl cloudSyncAssetManager; + return cloudSyncAssetManager; +} + +int32_t CloudSyncAssetManagerImpl::UploadAsset(const int32_t userId, const std::string& request, std::string& result) +{ + return 0; +} +int32_t CloudSyncAssetManagerImpl::DownloadFile(const int32_t userId, const std::string& bundleName, AssetInfo& assetInfo) +{ + return 0; +} +int32_t CloudSyncAssetManagerImpl::DeleteAsset(const int32_t userId, const std::string& uri) +{ + return 0; +} +int32_t CloudSyncAssetManagerImpl::DownloadFile(const int32_t userId, const std::string& bundleName, const std::string& networkId, + AssetInfo& assetInfo, CloudSyncAssetManager::ResultCallback resultCallback) +{ + return 0; +} +} // namespace OHOS::FileManagement::CloudSync \ No newline at end of file diff --git a/relational_store/CMakeLists.txt b/relational_store/CMakeLists.txt index 6733a42f..11e65f76 100644 --- a/relational_store/CMakeLists.txt +++ b/relational_store/CMakeLists.txt @@ -58,11 +58,11 @@ target_include_directories(relational_store PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/i add_library(js_relational_store SHARED ${js_common_src} ${js_relational_store_src}) -target_link_libraries(js_relational_store ${links} relational_store) +target_link_libraries(js_relational_store ${links} relational_store common_type) target_include_directories(js_relational_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/relationalstore/include) add_library(js_rdb_store SHARED ${js_common_src} ${js_rdb_store_src}) -target_link_libraries(js_rdb_store ${links} relational_store) +target_link_libraries(js_rdb_store ${links} relational_store common_type) target_include_directories(js_rdb_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/include) add_library(ndk_rdb_store SHARED ${ndk_rdb_store_src}) @@ -71,7 +71,7 @@ target_include_directories(ndk_rdb_store PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inte target_include_directories(ndk_rdb_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/ndk/src) add_library(js_dataability SHARED ${js_common_src} ${js_dataability_src}) -target_link_libraries(js_dataability mock relational_store js_rdb_store) +target_link_libraries(js_dataability mock relational_store js_rdb_store common_type) target_include_directories(js_dataability PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/include) @@ -83,5 +83,10 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/cloud_data/s aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/cloud_data/src cloud_data_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/common/src cloud_data_src) add_library(cloud_data SHARED ${cloud_data_src}) -target_link_libraries(cloud_data mock relational_store) -target_include_directories(cloud_data PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/cloud_data/include) \ No newline at end of file +target_link_libraries(cloud_data mock relational_store common_type) +target_include_directories(cloud_data PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/cloud_data/include) + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/common_type/src common_type_src) +add_library(common_type SHARED ${common_type_src}) +target_link_libraries(common_type mock relational_store) +target_include_directories(common_type PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/common_type/include) \ No newline at end of file diff --git a/relational_store/bundle.json b/relational_store/bundle.json index 9be1bb1d..acbbad09 100644 --- a/relational_store/bundle.json +++ b/relational_store/bundle.json @@ -77,13 +77,15 @@ "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb_data_share_adapter:rdb_data_share_adapter", "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb:native_rdb", "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb_bms_adapter:rdb_bms_adapter", + "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/common_type:common_type", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/cloud_data:clouddata", "//foundation/distributeddatamgr/relational_store/interfaces/ndk/src:native_rdb_ndk", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/dataability:dataability", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/rdb:rdb", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/rdb:napi_rdb", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/relationalstore:relationalstore", - "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/cloud_extension:cloudextension" + "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/cloud_extension:cloudextension", + "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/common:commontype_napi" ], "inner_kits": [ { @@ -169,6 +171,18 @@ ], "header_base": "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb_data_ability_adapter/include" } + }, + { + "name": "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/common_type:common_type", + "header": { + "header_files": [ + "common_value_object.h", + "common_asset_value.h", + "common_values_bucket.h", + "common_errno.h" + ], + "header_base": "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/common_type/include" + } } ], "test": [ diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_share.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_share.cpp index 3af9b8fc..11427d26 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_share.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_share.cpp @@ -58,13 +58,16 @@ napi_value AllocResourceAndShare(napi_env env, napi_callback_info info) int status = JSUtils::Convert2Value(env, argv[0], ctxt->storeId); ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of storeId must be string."); + // 'argv[1]' represents a RdbPredicates parameter status = JSUtils::Convert2Value(env, argv[1], ctxt->predicates); ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of predicates must be relationalStore.RdbPredicates"); + // 'argv[2]' represents a Participants parameter status = JSUtils::Convert2Value(env, argv[2], ctxt->participants); ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of participants must be Array."); - if (argc > 3) { + // 'argv[3]' represents an optional std::vector parameter + if (argc > 3 && !JSUtils::IsNull(env, argv[3])) { status = JSUtils::Convert2Value(env, argv[3], ctxt->columns); ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK, Status::INVALID_ARGUMENT, "The type of columns must be Array."); @@ -173,6 +176,7 @@ napi_value Unshare(napi_env env, napi_callback_info info) ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->participants.empty(), Status::INVALID_ARGUMENT, "The type of participants must be Array."); }); + ASSERT_NULL(!ctxt->isThrowError, "unShare exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -216,6 +220,7 @@ napi_value Exit(napi_env env, napi_callback_info info) ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->sharingRes.empty(), Status::INVALID_ARGUMENT, "The type of sharingRes must be string."); }); + ASSERT_NULL(!ctxt->isThrowError, "exit exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -245,7 +250,9 @@ napi_value Exit(napi_env env, napi_callback_info info) * callback: AsyncCallback>>>): void; * * [Promise] - * changePrivilege(sharingRes: string, participants: Array): Promise>>>; + * changePrivilege( + * sharingRes: string, + * participants: Array): Promise>>>; */ napi_value ChangePrivilege(napi_env env, napi_callback_info info) { @@ -264,6 +271,7 @@ napi_value ChangePrivilege(napi_env env, napi_callback_info info) ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->participants.empty(), Status::INVALID_ARGUMENT, "The type of participants must be Array."); }); + ASSERT_NULL(!ctxt->isThrowError, "changePrivilege exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -307,6 +315,7 @@ napi_value Query(napi_env env, napi_callback_info info) ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->sharingRes.empty(), Status::INVALID_ARGUMENT, "The type of sharingRes must be string."); }); + ASSERT_NULL(!ctxt->isThrowError, "query exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -351,6 +360,7 @@ napi_value QueryByInvitation(napi_env env, napi_callback_info info) ASSERT_BUSINESS_ERR(ctxt, status == JSUtils::OK && !ctxt->invitationCode.empty(), Status::INVALID_ARGUMENT, "The type of invitationCode must be string."); }); + ASSERT_NULL(!ctxt->isThrowError, "queryByInvitation exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -401,6 +411,7 @@ napi_value ConfirmInvitation(napi_env env, napi_callback_info info) Status::INVALID_ARGUMENT, "The type of status must be Status."); ctxt->confirmation = confirmation; }); + ASSERT_NULL(!ctxt->isThrowError, "confirmInvitation exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { @@ -451,6 +462,7 @@ napi_value ChangeConfirmation(napi_env env, napi_callback_info info) Status::INVALID_ARGUMENT, "The type of status must be Status."); ctxt->confirmation = confirmation; }); + ASSERT_NULL(!ctxt->isThrowError, "changeConfirmation exit"); auto execute = [env, ctxt]() { auto [status, proxy] = CloudManager::GetInstance().GetCloudService(); if (proxy == nullptr) { diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_utils.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_utils.cpp index 467ba63d..e19e284a 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_utils.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_cloud_utils.cpp @@ -59,12 +59,12 @@ int32_t Convert2Value(napi_env env, napi_value input, Participant &output) } NAPI_CALL_RETURN_ERR(GET_PROPERTY(env, input, output, identity), napi_invalid_arg); NAPI_CALL_RETURN_ERR(GetOptionalValue(env, input, "role", output.role), napi_invalid_arg); - if (output.role < CloudData::Role::ROLE_INVITER || output.role > CloudData::Role::ROLE_INVITEE) { + if (output.role < CloudData::Role::ROLE_NIL || output.role >= CloudData::Role::ROLE_BUTT) { return napi_invalid_arg; } NAPI_CALL_RETURN_ERR(GetOptionalValue(env, input, "state", output.state), napi_invalid_arg); - if (output.state < CloudData::Confirmation::CFM_UNKNOWN || - output.state > CloudData::Confirmation::CFM_SUSPENDED) { + if (output.state < CloudData::Confirmation::CFM_NIL || + output.state >= CloudData::Confirmation::CFM_BUTT) { return napi_invalid_arg; } NAPI_CALL_RETURN_ERR(GetOptionalValue(env, input, "privilege", output.privilege), napi_invalid_arg); @@ -114,8 +114,18 @@ napi_value Convert2JSValue(napi_env env, const Participant &value) return nullptr; } napi_value identity = Convert2JSValue(env, value.identity); - napi_value role = Convert2JSValue(env, value.role); - napi_value sharingState = Convert2JSValue(env, value.state); + napi_value role = nullptr; + if (value.role == CloudData::Role::ROLE_NIL) { + napi_get_undefined(env, &role); + } else { + role = Convert2JSValue(env, value.role); + } + napi_value state = nullptr; + if (value.state == CloudData::Confirmation::CFM_NIL) { + napi_get_undefined(env, &state); + } else { + state = Convert2JSValue(env, value.state); + } napi_value privilege = Convert2JSValue(env, value.privilege); if (privilege == nullptr) { return nullptr; @@ -123,7 +133,7 @@ napi_value Convert2JSValue(napi_env env, const Participant &value) napi_value attachInfo = Convert2JSValue(env, value.attachInfo); napi_set_named_property(env, jsValue, "identity", identity); napi_set_named_property(env, jsValue, "role", role); - napi_set_named_property(env, jsValue, "state", sharingState); + napi_set_named_property(env, jsValue, "state", state); napi_set_named_property(env, jsValue, "privilege", privilege); napi_set_named_property(env, jsValue, "attachInfo", attachInfo); return jsValue; diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp index e12c5d88..6fcd3446 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp @@ -18,6 +18,7 @@ #include "cloud_service.h" #include "cloud_types.h" #include "napi_queue.h" +#include "js_utils.h" using namespace OHOS::Rdb; using Action = OHOS::CloudData::CloudService::Action; @@ -92,6 +93,8 @@ napi_status InitConstProperties(napi_env env, napi_value exports) const napi_property_descriptor properties[] = { DECLARE_NAPI_PROPERTY("Action", ExportAction(env)), DECLARE_NAPI_PROPERTY("ClearAction", ExportAction(env)), + DECLARE_NAPI_PROPERTY("DATA_CHANGE_EVENT_ID", AppDataMgrJsKit::JSUtils::Convert2JSValue(env, + std::string(CloudData::DATA_CHANGE_EVENT_ID))), }; size_t count = sizeof(properties) / sizeof(properties[0]); diff --git a/relational_store/frameworks/js/napi/cloud_extension/cloud_extension.cpp b/relational_store/frameworks/js/napi/cloud_extension/cloud_extension.cpp index f4862727..9e9e667e 100644 --- a/relational_store/frameworks/js/napi/cloud_extension/cloud_extension.cpp +++ b/relational_store/frameworks/js/napi/cloud_extension/cloud_extension.cpp @@ -21,7 +21,8 @@ extern const char _binary_cloud_extension_abc_start[]; extern const char _binary_cloud_extension_abc_end[]; -extern "C" __attribute__((visibility("default"))) void NAPI_data_cloudExtension_GetABCCode(const char **buf, int *buflen) +extern "C" __attribute__((visibility("default"))) void NAPI_data_cloudExtension_GetABCCode( + const char **buf, int *buflen) { if (buf != nullptr) { *buf = _binary_cloud_extension_abc_start; diff --git a/relational_store/frameworks/js/napi/cloud_extension/cloud_sharing_types_util.js b/relational_store/frameworks/js/napi/cloud_extension/cloud_sharing_types_util.js index c70d3372..6831d7e7 100644 --- a/relational_store/frameworks/js/napi/cloud_extension/cloud_sharing_types_util.js +++ b/relational_store/frameworks/js/napi/cloud_extension/cloud_sharing_types_util.js @@ -23,7 +23,7 @@ export var cloudExtension; !function(e) { e[e.ConnectShareCenter = 0] = "ConnectShareCenter" }(t = e.CloudService_Function || (e.CloudService_Function = {})); - let a; + let r; !function(e) { e[e.Share = 0] = "Share"; e[e.Unshare = 1] = "Unshare"; @@ -32,161 +32,144 @@ export var cloudExtension; e[e.QueryParticipants = 4] = "QueryParticipants"; e[e.QueryParticipantsByInvitation = 5] = "QueryParticipantsByInvitation"; e[e.ConfirmInvitation = 6] = "ConfirmInvitation"; - e[e.ChangeConfirmation = 7] = "ChangeConfirmation" - }(a = e.ShareCenter_Function || (e.ShareCenter_Function = {})); + e[e.ChangeConfirmation = 7] = "ChangeConfirmation"; + }(r = e.ShareCenter_Function || (e.ShareCenter_Function = {})); - class r extends rpc.RemoteObject { + class n extends rpc.RemoteObject { constructor(e, t) { super(e); this.cloudService = t; - console.info(`${TAG} CloudServiceProxy constructor`) + console.info(`${TAG} CloudServiceProxy constructor`); } - async onRemoteMessageRequest(e, a, r, n) { - console.info(`${TAG}, onRemoteRequest called, code = ${e}`); - n.setWaitTime(1e3); + async onRemoteMessageRequest(e, r, n, i) { + console.info(`${TAG}, onRemoteRequest called, code: ${e}`); + i.setWaitTime(1e3); if (e === t.ConnectShareCenter) { - let e = a.readInt(); - let t = a.readInt(); - let n = this.unMarshallingString(a.readRawData(t)); - let i = await this.cloudService.connectShareCenter(e, n); - null == i && console.error(`${TAG}, sharingCenter is null`); - r.writeRemoteObject(i); - return !0 + let e = r.readInt(); + let t = r.readString(); + let i = await this.cloudService.connectShareCenter(e, t); + if (null == i) { + console.error(`${TAG}, sharingCenter is null`); + return !1; + } + n.writeRemoteObject(i); + return !0; } - console.error(`${TAG}, invalid request code ${e}`); - return !1 - } - - unMarshallingString(e) { - let t = ""; - e.forEach((e => { - t += String.fromCharCode(e) - })); - return t.toString() + console.error(`${TAG}, invalid request code: ${e}`); + return !1; } } - e.CloudServiceProxy = r; + e.CloudServiceProxy = n; - class n extends rpc.RemoteObject { + class i extends rpc.RemoteObject { constructor(e, t) { super(e); this.shareCenter = t; - console.info(`${TAG} shareCenter constructor`) + console.info(`${TAG} shareCenter constructor`); } - async onRemoteMessageRequest(e, t, r, n) { - console.info(`${TAG}, onRemoteRequest called, code = = ${e}`); - if (void 0 === this.shareCenter) return !1; - n.setWaitTime(1500); + async onRemoteMessageRequest(e, t, n, i) { + console.info(`${TAG}, shareCenter onRemoteRequest called, code: ${e}`); + if (null == this.shareCenter) { + console.info(`${TAG}, shareCenter undefined`); + return !1; + } + i.setWaitTime(1500); switch(e) { - case a.Share: + case r.Share: let e = t.readInt(); - let n = t.readInt(); - let i = this.unMarshallingString(t.readRawData(n)); - let l = t.readInt(); - let s = this.unMarshallingString(t.readRawData(l)); - let o = this.unMarshallingParticipants(t); - let h = await this.shareCenter.share(e, i, s, o); - this.marshallingResults(r, h); + let i = t.readString(); + let a = t.readString(); + let l = this.unMarshallingParticipants(t); + let o = await this.shareCenter.share(e, i, a, l); + this.marshallingResults(n, o); return !0; - case a.Unshare: - let c = t.readInt(); - let u = t.readInt(); - let g = this.unMarshallingString(t.readRawData(u)); - let d = t.readInt(); - let I = this.unMarshallingString(t.readRawData(d)); - let w = this.unMarshallingParticipants(t); - let S = await this.shareCenter.unshare(c, g, I, w); - this.marshallingResults(r, S); + case r.Unshare: + let s = t.readInt(); + let c = t.readString(); + let h = t.readString(); + let d = this.unMarshallingParticipants(t); + let u = await this.shareCenter.unshare(s, c, h, d); + this.marshallingResults(n, u); return !0; - case a.Exit: - let C = t.readInt(); - let m = t.readInt(); - let f = this.unMarshallingString(t.readRawData(m)); - let p = t.readInt(); - let v = this.unMarshallingString(t.readRawData(p)); - let R = await this.shareCenter.exit(C, f, v); - r.writeInt(R.code); - R.description ? this.marshallingString(r, R.description) : r.writeInt(0); + case r.Exit: + let g = t.readInt(); + let S = t.readString(); + let w = t.readString(); + let C = await this.shareCenter.exit(g, S, w); + n.writeInt(C.code); + C.description ? n.writeString(C.description) : n.writeString(""); return !0; - case a.ChangePrivilege: - let M = t.readInt(); - let P = t.readInt(); - let y = this.unMarshallingString(t.readRawData(P)); - let D = t.readInt(); - let x = this.unMarshallingString(t.readRawData(D)); - let b = this.unMarshallingParticipants(t); - let $ = await this.shareCenter.changePrivilege(M, y, x, b); - this.marshallingResults(r, $); + case r.ChangePrivilege: + let v = t.readInt(); + let p = t.readString(); + let I = t.readString(); + let f = this.unMarshallingParticipants(t); + let m = await this.shareCenter.changePrivilege(v, p, I, f); + this.marshallingResults(n, m); return !0; - case a.QueryParticipants: - let B = t.readInt(); - let A = t.readInt(); - let E = this.unMarshallingString(t.readRawData(A)); - let T = t.readInt(); - let q = this.unMarshallingString(t.readRawData(T)); - let j = await this.shareCenter.queryParticipants(B, E, q); - this.marshallingResultsArray(r, j); + case r.QueryParticipants: + let P = t.readInt(); + let y = t.readString(); + let B = t.readString(); + let R = await this.shareCenter.queryParticipants(P, y, B); + this.marshallingResultsArray(n, R); return !0; - case a.QueryParticipantsByInvitation: - let G = t.readInt(); - let Q = t.readInt(); - let F = this.unMarshallingString(t.readRawData(Q)); - let O = t.readInt(); - let _ = this.unMarshallingString(t.readRawData(O)); - let z = await this.shareCenter.queryParticipantsByInvitation(G, F, _); - this.marshallingResultsArray(r, z); + case r.QueryParticipantsByInvitation: + let x = t.readInt(); + let A = t.readString(); + let b = t.readString(); + let T = await this.shareCenter.queryParticipantsByInvitation(x, A, b); + this.marshallingResultsArray(n, T); return !0; - case a.ConfirmInvitation: - let U = t.readInt(); - let W = t.readInt(); - let J = this.unMarshallingString(t.readRawData(W)); - let N = t.readInt(); - let k = this.unMarshallingString(t.readRawData(N)); - let H = t.readInt(); - let K = await this.shareCenter.confirmInvitation(U, J, k, H); - r.writeInt(K.code); - K.description ? this.marshallingString(r, K.description) : r.writeInt(0); - K.value ? this.marshallingString(r, K.value) : r.writeInt(0); + case r.ConfirmInvitation: + let $ = t.readInt(); + let E = t.readString(); + let G = t.readString(); + let M = t.readInt(); + let q = await this.shareCenter.confirmInvitation($, E, G, M); + n.writeInt(q.code); + q.description ? n.writeString(q.description) : n.writeString(""); + q.value ? n.writeString(q.value) : n.writeString(""); return !0; - case a.ChangeConfirmation: - let L = t.readInt(); - let V = t.readInt(); - let X = this.unMarshallingString(t.readRawData(V)); - let Y = t.readInt(); - let Z = this.unMarshallingString(t.readRawData(Y)); - let ee = t.readInt(); - let te = await this.shareCenter.changeConfirmation(L, X, Z, ee); - r.writeInt(te.code); - te.description ? this.marshallingString(r, te.description) : r.writeInt(0); + case r.ChangeConfirmation: + let Q = t.readInt(); + let _ = t.readString(); + let F = t.readString(); + let j = t.readInt(); + let O = await this.shareCenter.changeConfirmation(Q, _, F, j); + n.writeInt(O.code); + O.description ? n.writeString(O.description) : n.writeString(""); return !0; default: - console.info(`${TAG}, invalid request code`) + console.info(`${TAG}, invalid request code`); } return !1 } unMarshallingParticipants(e) { let t = []; - let a = e.readInt(); - console.info(`${TAG}, query fields length = ${a}`); - for (let r = 0; r < a; r++) t.push(this.unMarshallingParticipant(e)); - return t + let r = e.readInt(); + console.info(`${TAG}, array length: ${r}`); + for (let n = 0; n < r; n++) t.push(this.unMarshallingParticipant(e)); + return t; } unMarshallingParticipant(e) { - let t = e.readInt(); - let a; - a = { - identity: this.unMarshallingString(e.readRawData(t)), - role: e.readInt(), - state: e.readInt(), + let t = e.readString(); + let r; + let n = e.readInt(); + let i = e.readInt(); + r = { + identity: t, + role: -1 == n ? void 0 : n, + state: -1 == i ? void 0 : i, privilege: this.unMarshallingPrivilege(e), - attachInfo: this.unMarshallingString(e.readRawData(e.readInt())) + attachInfo: e.readString() }; - return a + return r; } unMarshallingPrivilege(e) { @@ -198,38 +181,44 @@ export var cloudExtension; deletable: e.readBoolean(), shareable: e.readBoolean() }; - return t + return t; } marshallingResultsArray(e, t) { e.writeInt(t.code); - t.description ? this.marshallingString(e, t.description) : e.writeInt(0); + t.description ? e.writeString(t.description) : e.writeString(""); if (t.value) { e.writeInt(t.value.length); t.value.forEach((t => { - this.marshallingParticipant(e, t) + this.marshallingParticipant(e, t); })) } } marshallingResults(e, t) { e.writeInt(t.code); - t.description ? this.marshallingString(e, t.description) : e.writeInt(0); + t.description ? e.writeString(t.description) : e.writeString(""); if (t.value) { e.writeInt(t.value.length); t.value.forEach((t => { e.writeInt(t.code); - t.description ? this.marshallingString(e, t.description) : e.writeInt(0) + t.description ? e.writeString(t.description) : e.writeString(""); })) } } marshallingParticipant(e, t) { - this.marshallingString(e, t.identity); - e.writeInt(t.role); - e.writeInt(t.state); - t.privilege && this.marshallingPrivilege(e, t.privilege); - t.attachInfo ? this.marshallingString(e, t.attachInfo) : e.writeInt(0) + e.writeString(t.identity); + void 0 !== t.role? e.writeInt(t.role) : e.writeInt(-1); + void 0 !== t.state? e.writeInt(t.state) : e.writeInt(-1); + if (t.privilege) this.marshallingPrivilege(e, t.privilege); else { + e.writeBoolean(!1); + e.writeBoolean(!1); + e.writeBoolean(!1); + e.writeBoolean(!1); + e.writeBoolean(!1); + } + t.attachInfo ? e.writeString(t.attachInfo) : e.writeString(""); } marshallingPrivilege(e, t) { @@ -237,34 +226,16 @@ export var cloudExtension; e.writeBoolean(t.readable); e.writeBoolean(t.creatable); e.writeBoolean(t.deletable); - e.writeBoolean(t.shareable) - } - - unMarshallingString(e) { - let t = ""; - e.forEach((e => { - t += String.fromCharCode(e) - })); - return t.toString() - } - - marshallingString(e, t) { - let a = []; - let r; - r = t; - let n = t.length; - e.writeInt(n); - for (let e = 0; e < n; e++) a.push(r.charCodeAt(e)); - e.writeRawData(a, n) + e.writeBoolean(t.shareable); } } - e.ShareCenterProxy = n; + e.ShareCenterProxy = i; e.createCloudServiceStub = async function (e) { - return new r("CloudServiceProxy", e) + return new n('CloudServiceProxy', e); }; e.createShareServiceStub = async function (e) { - return new n("ShareCenterProxy", e) + return new i('ShareCenterProxy', e); } }(cloudExtension || (cloudExtension = {})); diff --git a/relational_store/frameworks/js/napi/rdb/BUILD.gn b/relational_store/frameworks/js/napi/rdb/BUILD.gn index 2e4374e8..62e326ec 100644 --- a/relational_store/frameworks/js/napi/rdb/BUILD.gn +++ b/relational_store/frameworks/js/napi/rdb/BUILD.gn @@ -38,6 +38,7 @@ ohos_shared_library("napi_rdb") { if (is_mingw || is_mac) { include_dirs = [ "mock/include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/mock/include", "${relational_store_napi_path}/rdb/mock/include", @@ -75,6 +76,7 @@ ohos_shared_library("napi_rdb") { include_dirs = [ "include", "${datashare_path}/common/include/", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/include", "${relational_store_napi_path}/rdb/include", diff --git a/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h b/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h index 22f532aa..4ad567b7 100644 --- a/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h +++ b/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h @@ -19,6 +19,7 @@ #include #include "abs_shared_result_set.h" +#include "js_proxy.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -27,7 +28,7 @@ namespace OHOS { namespace RdbJsKit { -class ResultSetProxy final : public DataShare::ResultSetBridge::Creator { +class ResultSetProxy final : public JSProxy::JSEntity { public: ResultSetProxy() = default; ~ResultSetProxy(); @@ -81,7 +82,6 @@ private: static napi_value GetSharedBlockName(napi_env env, napi_callback_info info); static napi_value GetSharedBlockAshmemFd(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_; std::shared_ptr sharedResultSet_; std::string sharedBlockName_; diff --git a/relational_store/frameworks/js/napi/rdb/mock/include/napi_result_set.h b/relational_store/frameworks/js/napi/rdb/mock/include/napi_result_set.h index 3be1867e..2b93ee43 100644 --- a/relational_store/frameworks/js/napi/rdb/mock/include/napi_result_set.h +++ b/relational_store/frameworks/js/napi/rdb/mock/include/napi_result_set.h @@ -18,6 +18,7 @@ #include +#include "js_proxy.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -26,7 +27,7 @@ namespace OHOS { namespace RdbJsKit { -class ResultSetProxy final { +class ResultSetProxy final : public JSProxy::JSProxy { public: ResultSetProxy() = default; ~ResultSetProxy(); @@ -76,8 +77,6 @@ private: static napi_value GetSharedBlockName(napi_env env, napi_callback_info info); static napi_value GetSharedBlockAshmemFd(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_; - std::string sharedBlockName_; int32_t sharedBlockAshmemFd_ = -1; }; diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp index 85cc3539..7349d9c8 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp @@ -103,11 +103,11 @@ std::shared_ptr ResultSetProxy::GetNativeObject( std::shared_ptr ResultSetProxy::Create() { - if (resultSet_ == nullptr) { + if (GetInstance() == nullptr) { LOG_ERROR("resultSet_ is null"); return nullptr; } - return std::make_shared(std::move(resultSet_)); + return std::make_shared(GetInstance()); } #endif @@ -206,18 +206,18 @@ ResultSetProxy::~ResultSetProxy() ResultSetProxy::ResultSetProxy(std::shared_ptr resultSet) { - if (resultSet_ == resultSet) { + if (GetInstance() == resultSet) { return; } - resultSet_ = std::move(resultSet); + SetInstance(std::move(resultSet)); } ResultSetProxy &ResultSetProxy::operator=(std::shared_ptr resultSet) { - if (resultSet_ == resultSet) { + if (GetInstance() == resultSet) { return *this; } - resultSet_ = std::move(resultSet); + SetInstance(std::move(resultSet)); return *this; } @@ -227,7 +227,7 @@ ResultSetProxy *ResultSetProxy::GetInnerResultSet(napi_env env, napi_callback_in napi_value self = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr); napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)); - RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy && resultSetProxy->resultSet_, std::make_shared(), + RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy && resultSetProxy->GetInstance(), std::make_shared(), resultSetProxy->apiversion); version = resultSetProxy->apiversion; @@ -244,7 +244,7 @@ ResultSetProxy *ResultSetProxy::ParseInt32FieldByName( napi_get_cb_info(env, info, &argc, args, &self, nullptr); ResultSetProxy *resultSetProxy = nullptr; napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)); - RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy && resultSetProxy->resultSet_, + RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy && resultSetProxy->GetInstance(), std::make_shared("resultSet", "not null"), resultSetProxy->apiversion); RDB_NAPI_ASSERT_FROMV9( env, argc == 1, std::make_shared("1"), resultSetProxy->apiversion); @@ -263,7 +263,7 @@ ResultSetProxy *ResultSetProxy::ParseFieldByName(napi_env env, napi_callback_inf napi_get_cb_info(env, info, &argc, args, &self, nullptr); ResultSetProxy *resultSetProxy = nullptr; napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); RDB_NAPI_ASSERT_FROMV9( env, argc == 1, std::make_shared("1"), resultSetProxy->apiversion); @@ -276,9 +276,9 @@ napi_value ResultSetProxy::GetAllColumnNames(napi_env env, napi_callback_info in std::vector colNames; int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetAllColumnNames(colNames); + int errCode = resultSetProxy->GetInstance()->GetAllColumnNames(colNames); if (errCode != E_OK) { LOG_ERROR("GetAllColumnNames failed code:%{public}d, version:%{public}d", errCode, version); } @@ -289,9 +289,9 @@ napi_value ResultSetProxy::GoToRow(napi_env env, napi_callback_info info) { int32_t position; auto resultSetProxy = ParseInt32FieldByName(env, info, position, "position"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoToRow(position); + int errCode = resultSetProxy->GetInstance()->GoToRow(position); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -300,9 +300,9 @@ napi_value ResultSetProxy::GetColumnCount(napi_env env, napi_callback_info info) int32_t count = 0; int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetColumnCount(count); + int errCode = resultSetProxy->GetInstance()->GetColumnCount(count); if (errCode != E_OK) { LOG_ERROR("GetColumnCount failed code:%{public}d, version:%{public}d", errCode, version); } @@ -314,9 +314,9 @@ napi_value ResultSetProxy::GetLong(napi_env env, napi_callback_info info) int32_t columnIndex; int64_t result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetLong(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetLong(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); return JSUtils::Convert2JSValue(env, result); @@ -327,9 +327,9 @@ napi_value ResultSetProxy::GetColumnType(napi_env env, napi_callback_info info) int32_t columnIndex; ColumnType columnType; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetColumnType(columnIndex, columnType); + int errCode = resultSetProxy->GetInstance()->GetColumnType(columnIndex, columnType); if (errCode != E_OK) { LOG_ERROR("GetColumnType failed code:%{public}d, version:%{public}d", errCode, resultSetProxy->apiversion); } @@ -340,9 +340,9 @@ napi_value ResultSetProxy::GoTo(napi_env env, napi_callback_info info) { int32_t offset; auto resultSetProxy = ParseInt32FieldByName(env, info, offset, "offset"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoTo(offset); + int errCode = resultSetProxy->GetInstance()->GoTo(offset); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -351,9 +351,9 @@ napi_value ResultSetProxy::GetColumnIndex(napi_env env, napi_callback_info info) std::string input; int32_t result = -1; auto resultSetProxy = ParseFieldByName(env, info, input); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetColumnIndex(input, result); + int errCode = resultSetProxy->GetInstance()->GetColumnIndex(input, result); if (errCode != E_OK) { LOG_ERROR("GetColumnIndex failed code:%{public}d, version:%{public}d", errCode, resultSetProxy->apiversion); } @@ -365,9 +365,9 @@ napi_value ResultSetProxy::GetInt(napi_env env, napi_callback_info info) int32_t columnIndex; int32_t result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetInt(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetInt(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); return JSUtils::Convert2JSValue(env, result); @@ -378,9 +378,9 @@ napi_value ResultSetProxy::GetColumnName(napi_env env, napi_callback_info info) int32_t columnIndex; std::string result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetColumnName(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetColumnName(columnIndex, result); if (errCode != E_OK) { LOG_ERROR("GetColumnName failed code:%{public}d, version:%{public}d", errCode, resultSetProxy->apiversion); } @@ -391,9 +391,9 @@ napi_value ResultSetProxy::Close(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->Close(); + int errCode = resultSetProxy->GetInstance()->Close(); RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); napi_value result = nullptr; napi_get_null(env, &result); @@ -404,10 +404,10 @@ napi_value ResultSetProxy::GetRowCount(napi_env env, napi_callback_info info) { int version = 0; ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); int32_t result; - int errCode = resultSetProxy->resultSet_->GetRowCount(result); + int errCode = resultSetProxy->GetInstance()->GetRowCount(result); if (errCode != E_OK) { LOG_ERROR("GetRowCount failed code:%{public}d, version:%{public}d", errCode, version); } @@ -418,10 +418,10 @@ napi_value ResultSetProxy::GetRowIndex(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); int32_t result; - int errCode = resultSetProxy->resultSet_->GetRowIndex(result); + int errCode = resultSetProxy->GetInstance()->GetRowIndex(result); if (errCode != E_OK) { LOG_ERROR("GetRowIndex failed code:%{public}d, version:%{public}d", errCode, version); } @@ -432,10 +432,10 @@ napi_value ResultSetProxy::IsEnded(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); bool result = false; - int errCode = resultSetProxy->resultSet_->IsEnded(result); + int errCode = resultSetProxy->GetInstance()->IsEnded(result); if (errCode != E_OK) { LOG_ERROR("IsEnded failed code:%{public}d, version:%{public}d", errCode, version); } @@ -446,10 +446,10 @@ napi_value ResultSetProxy::IsBegin(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); bool result = false; - int errCode = resultSetProxy->resultSet_->IsStarted(result); + int errCode = resultSetProxy->GetInstance()->IsStarted(result); if (errCode != E_OK) { LOG_ERROR("IsBegin failed code:%{public}d, version:%{public}d", errCode, version); } @@ -460,9 +460,9 @@ napi_value ResultSetProxy::GoToFirstRow(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoToFirstRow(); + int errCode = resultSetProxy->GetInstance()->GoToFirstRow(); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -470,9 +470,9 @@ napi_value ResultSetProxy::GoToLastRow(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoToLastRow(); + int errCode = resultSetProxy->GetInstance()->GoToLastRow(); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -480,9 +480,9 @@ napi_value ResultSetProxy::GoToNextRow(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoToNextRow(); + int errCode = resultSetProxy->GetInstance()->GoToNextRow(); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -490,9 +490,9 @@ napi_value ResultSetProxy::GoToPreviousRow(napi_env env, napi_callback_info info { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GoToPreviousRow(); + int errCode = resultSetProxy->GetInstance()->GoToPreviousRow(); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -500,10 +500,10 @@ napi_value ResultSetProxy::IsAtFirstRow(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); bool result = false; - int errCode = resultSetProxy->resultSet_->IsAtFirstRow(result); + int errCode = resultSetProxy->GetInstance()->IsAtFirstRow(result); if (errCode != E_OK) { LOG_ERROR("IsAtFirstRow failed code:%{public}d, version:%{public}d", errCode, version); } @@ -514,10 +514,10 @@ napi_value ResultSetProxy::IsAtLastRow(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); bool result = false; - int errCode = resultSetProxy->resultSet_->IsAtLastRow(result); + int errCode = resultSetProxy->GetInstance()->IsAtLastRow(result); if (errCode != E_OK) { LOG_ERROR("IsAtLastRow failed code:%{public}d, version:%{public}d", errCode, version); } @@ -530,9 +530,9 @@ napi_value ResultSetProxy::GetBlob(napi_env env, napi_callback_info info) int32_t columnIndex; std::vector result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetBlob(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetBlob(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); return JSUtils::Convert2JSValue(env, result); @@ -544,9 +544,9 @@ napi_value ResultSetProxy::GetString(napi_env env, napi_callback_info info) int32_t columnIndex; std::string result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetString(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetString(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); return JSUtils::Convert2JSValue(env, result); @@ -557,9 +557,9 @@ napi_value ResultSetProxy::GetDouble(napi_env env, napi_callback_info info) int32_t columnIndex; double result = 0.0; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->GetDouble(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->GetDouble(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); return JSUtils::Convert2JSValue(env, result); @@ -570,9 +570,9 @@ napi_value ResultSetProxy::IsColumnNull(napi_env env, napi_callback_info info) int32_t columnIndex; bool result = false; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int errCode = resultSetProxy->resultSet_->IsColumnNull(columnIndex, result); + int errCode = resultSetProxy->GetInstance()->IsColumnNull(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); napi_value output = nullptr; @@ -584,9 +584,9 @@ napi_value ResultSetProxy::IsClosed(napi_env env, napi_callback_info info) { int version = 0; auto resultSetProxy = GetInnerResultSet(env, info, version); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->resultSet_, "resultSetProxy or resultSet_ is nullptr"); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy && resultSetProxy->GetInstance(), "Proxy or instance is nullptr"); - int result = resultSetProxy->resultSet_->IsClosed(); + int result = resultSetProxy->GetInstance()->IsClosed(); napi_value output = nullptr; napi_get_boolean(env, result, &output); return output; diff --git a/relational_store/frameworks/js/napi/relationalstore/BUILD.gn b/relational_store/frameworks/js/napi/relationalstore/BUILD.gn index 3c860439..b6205a21 100644 --- a/relational_store/frameworks/js/napi/relationalstore/BUILD.gn +++ b/relational_store/frameworks/js/napi/relationalstore/BUILD.gn @@ -47,6 +47,7 @@ if (is_ohos) { include_dirs = [ "include", "${datashare_path}/common/include/", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/include", "${relational_store_napi_path}/relationalstore/include", @@ -83,6 +84,7 @@ if (is_ohos) { ohos_shared_library("relationalstore") { include_dirs = [ "mock/include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/mock/include", "${relational_store_napi_path}/relationalstore/mock/include", @@ -117,6 +119,7 @@ if (is_ohos) { ohos_shared_library("relationalstore") { include_dirs = [ "mock/include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/mock/include", "${relational_store_napi_path}/relationalstore/mock/include", @@ -149,6 +152,7 @@ if (is_ohos) { ohos_source_set("data_relationalstore") { include_dirs = [ "mock/include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/mock/include", "include", @@ -185,6 +189,7 @@ if (is_ohos) { ohos_source_set("data_relationalstore") { include_dirs = [ "mock/include", + "${kvstore_path}/common", "${relational_store_common_path}/include", "${relational_store_js_common_path}/mock/include", "include", diff --git a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_result_set.h b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_result_set.h index 4d3ab59a..f3190f33 100644 --- a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_result_set.h +++ b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_result_set.h @@ -18,6 +18,7 @@ #include +#include "js_proxy.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -25,7 +26,7 @@ namespace OHOS { namespace RelationalStoreJsKit { -class ResultSetProxy final { +class ResultSetProxy final : public JSProxy::JSProxy { public: ResultSetProxy() = default; ~ResultSetProxy(); @@ -74,8 +75,6 @@ private: static napi_value GetSharedBlockName(napi_env env, napi_callback_info info); static napi_value GetSharedBlockAshmemFd(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_; - std::string sharedBlockName_; int32_t sharedBlockAshmemFd_ = -1; }; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp index f3b8eaa6..f9673dba 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp @@ -1524,14 +1524,12 @@ napi_value RdbStoreProxy::QuerySharingResource(napi_env env, napi_callback_info auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc > 0 && argc < 4, std::make_shared("1 to 3")); CHECK_RETURN(OK == ParserThis(env, self, context)); + // 'argv[0]' represents a RdbPredicates parameter CHECK_RETURN(OK == ParsePredicates(env, argv[0], context)); - if (argc >= 2) { - bool isArray = false; - napi_is_array(env, argv[1], &isArray); - if (isArray) { - CHECK_RETURN(OK == ParseColumns(env, argv[1], context)); - } - } + // 'argv[1]' represents an optional std::vector parameter + CHECK_RETURN(argc < 2 || JSUtils::IsNull(env, argv[1]) || OK == ParseColumns(env, argv[1], context)); + RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_SET_E(obj != nullptr && obj->IsSystemAppCalled(), std::make_shared()); }; auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::QuerySharingResource Async"); @@ -1542,7 +1540,7 @@ napi_value RdbStoreProxy::QuerySharingResource(napi_env env, napi_callback_info obj->rdbStore_->QuerySharingResource(*(context->rdbPredicates), context->columns); LOG_DEBUG("RdbStoreProxy::QuerySharingResource resultSet is nullptr:%{public}d, status:%{public}d", context->resultSet == nullptr, status); - return (context->resultSet != nullptr) ? E_OK : E_ERROR; + return (status == E_OK && context->resultSet != nullptr) ? E_OK : E_ERROR; }; auto output = [context](napi_env env, napi_value &result) { result = ResultSetProxy::NewInstance(env, context->resultSet); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp index 7d00f589..b8172f54 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp @@ -135,15 +135,23 @@ int ParseDatabasePath(const napi_env &env, const napi_value &object, std::shared if (status == napi_ok && hasProp) { napi_value value = nullptr; napi_get_named_property(env, object, "customDir", &value); - CHECK_RETURN_SET(value != nullptr, std::make_shared("config", "a StoreConfig.")); + CHECK_RETURN_SET(value != nullptr, std::make_shared("customDir", "a valid value.")); JSUtils::Convert2Value(env, value, customDir); + + size_t pos = customDir.find_first_of('/'); + // determine if the first character of customDir is '/' + CHECK_RETURN_SET(pos != 0, std::make_shared("customDir", "a relative directory.")); + // customDir length is limited to 128 bytes + CHECK_RETURN_SET(customDir.length() <= 128, + std::make_shared("customDir length", "less than or equal to 128 bytes.")); + context->config.SetCustomDir(customDir); } auto [realPath, errCode] = RdbSqlUtils::GetDefaultDatabasePath(defaultDir, context->config.GetName(), customDir); - // customDir length is limited to 128 bytes - CHECK_RETURN_SET(errCode == E_OK && realPath.length() <= 128, - std::make_shared("config", "a StoreConfig.")); + // realPath length is limited to 1024 bytes + CHECK_RETURN_SET(errCode == E_OK && realPath.length() <= 1024, + std::make_shared("database path", "a valid path.")); context->config.SetPath(std::move(realPath)); return OK; diff --git a/relational_store/frameworks/native/cloud_data/src/cloud_types_util.cpp b/relational_store/frameworks/native/cloud_data/src/cloud_types_util.cpp index b811d9d4..5d519c15 100644 --- a/relational_store/frameworks/native/cloud_data/src/cloud_types_util.cpp +++ b/relational_store/frameworks/native/cloud_data/src/cloud_types_util.cpp @@ -54,7 +54,7 @@ template<> bool Unmarshalling(Role &output, MessageParcel &data) { int32_t result; - if (!data.ReadInt32(result) || result <= Role::ROLE_NIL || result >= Role::ROLE_BUTT) { + if (!data.ReadInt32(result) || result < Role::ROLE_NIL || result >= Role::ROLE_BUTT) { return false; } output = static_cast(result); @@ -71,7 +71,7 @@ template<> bool Unmarshalling(Confirmation &output, MessageParcel &data) { int32_t result; - if (!data.ReadInt32(result) || result <= Confirmation::CFM_NIL || + if (!data.ReadInt32(result) || result < Confirmation::CFM_NIL || result >= Confirmation::CFM_BUTT) { return false; } diff --git a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h index d9300858..251b1939 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h +++ b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h @@ -58,8 +58,8 @@ public: int32_t UnregisterAutoSyncCallback( const RdbSyncerParam ¶m, std::shared_ptr observer) override; - int32_t RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) override; + std::pair> RemoteQuery(const RdbSyncerParam ¶m, const std::string &device, + const std::string &sql, const std::vector &selectionArgs) override; Observers ExportObservers(); @@ -71,7 +71,7 @@ public: int32_t NotifyDataChange(const RdbSyncerParam& param, const RdbChangedData &clientChangedData) override; - std::pair> QuerySharingResource(const RdbSyncerParam ¶m, + std::pair> QuerySharingResource(const RdbSyncerParam ¶m, const PredicatesMemo &predicates, const std::vector &columns) override; private: using ChangeInfo = RdbStoreObserver::ChangeInfo; diff --git a/relational_store/frameworks/native/rdb/src/cache_result_set.cpp b/relational_store/frameworks/native/rdb/src/cache_result_set.cpp index 7673ff76..12f05b43 100644 --- a/relational_store/frameworks/native/rdb/src/cache_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/cache_result_set.cpp @@ -44,7 +44,7 @@ CacheResultSet::~CacheResultSet() int CacheResultSet::GetRowCount(int &count) { - count = static_cast(colNames_.size()); + count = static_cast(maxRow_); return E_OK; } @@ -153,13 +153,13 @@ int CacheResultSet::GetRow(RowEntity &rowEntity) int CacheResultSet::GoToRow(int position) { std::unique_lock lock(rwMutex_); - if (position > maxRow_) { + if (position >= maxRow_) { row_ = maxRow_; - return E_OK; + return E_ERROR; } if (position < 0) { - row_ = 0; - return E_OK; + row_ = -1; + return E_ERROR; } row_ = position; return E_OK; @@ -245,7 +245,8 @@ int CacheResultSet::IsEnded(bool &result) int CacheResultSet::GetColumnCount(int &count) { - return static_cast(colNames_.size()); + count = maxCol_; + return E_OK; } int CacheResultSet::GetColumnIndex(const std::string &columnName, int &columnIndex) diff --git a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp index 97b7f04a..a210f59f 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -18,6 +18,7 @@ #include "itypes_util.h" #include "logger.h" #include "sqlite_utils.h" +#include "result_set_proxy.h" namespace OHOS::DistributedRdb { using namespace OHOS::Rdb; @@ -280,25 +281,26 @@ int32_t RdbServiceProxy::DoUnSubscribe(const RdbSyncerParam ¶m) return status; } -int32_t RdbServiceProxy::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) +std::pair> RdbServiceProxy::RemoteQuery( + const RdbSyncerParam ¶m, const std::string &device, const std::string &sql, + const std::vector &selectionArgs) { MessageParcel reply; int32_t status = IPC_SEND( static_cast(RdbServiceCode::RDB_SERVICE_CMD_REMOTE_QUERY), reply, param, device, sql, selectionArgs); if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, device:%{public}.6s", - status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), device.c_str()); - return status; + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, device:%{public}.6s", status, + param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), device.c_str()); + return { status, nullptr }; } sptr remote = reply.ReadRemoteObject(); if (remote == nullptr) { LOG_ERROR("read remote object is null"); - return RDB_ERROR; + return { RDB_ERROR, nullptr }; } - resultSet = remote; - return RDB_OK; + sptr instance = new NativeRdb::ResultSetProxy(remote); + return { RDB_OK, std::shared_ptr(instance.GetRefPtr(), [holder = instance](const auto *) {}) }; } RdbServiceProxy::Observers RdbServiceProxy::ExportObservers() @@ -342,19 +344,23 @@ int32_t RdbServiceProxy::Delete(const RdbSyncerParam ¶m) return status; } -std::pair> RdbServiceProxy::QuerySharingResource( +std::pair> RdbServiceProxy::QuerySharingResource( const RdbSyncerParam ¶m, const PredicatesMemo &predicates, const std::vector &columns) { MessageParcel reply; int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_QUERY_SHARING_RESOURCE), reply, param, predicates, columns); - std::vector valueBuckets; - bool success = ITypesUtil::Unmarshal(reply, valueBuckets); - if (status != RDB_OK || !success) { - LOG_ERROR("status:%{public}d, valueBuckets size:%{public}zu", status, valueBuckets.size()); + sptr remote; + bool success = ITypesUtil::Unmarshal(reply, remote); + if (status != RDB_OK || !success || remote == nullptr) { + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, success:%{public}d, remote is " + "%{public}s nullptr", + status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), success, + remote != nullptr ? "not" : ""); return { RDB_ERROR, {} }; } - return { RDB_OK, valueBuckets }; + sptr instance = new NativeRdb::ResultSetProxy(remote); + return { RDB_OK, std::shared_ptr(instance.GetRefPtr(), [instance](const auto *) {}) }; } int32_t RdbServiceProxy::RegisterAutoSyncCallback( diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp index cc09a8f4..bf267262 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -627,9 +627,12 @@ std::pair> RdbStoreImpl::QuerySharingResourc if (errCode != E_OK) { return { errCode, nullptr }; } - auto [status, valueBuckets] = + auto [status, resultSet] = service->QuerySharingResource(syncerParam_, predicates.GetDistributedPredicates(), columns); - return { status, std::make_shared(std::move(valueBuckets)) }; + if (status != E_OK) { + return { status, nullptr }; + } + return { status, resultSet }; } std::shared_ptr RdbStoreImpl::QueryByStep( @@ -647,17 +650,14 @@ std::shared_ptr RdbStoreImpl::RemoteQuery(const std::string &device, std::vector selectionArgs = predicates.GetWhereArgs(); std::string sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); - errCode = err; if (err != E_OK) { LOG_ERROR("RdbStoreImpl::RemoteQuery get service failed"); + errCode = err; return nullptr; } - sptr remoteResultSet; - if (service->RemoteQuery(syncerParam_, device, sql, selectionArgs, remoteResultSet) != E_OK) { - LOG_ERROR("RdbStoreImpl::RemoteQuery service RemoteQuery failed"); - return nullptr; - } - return std::make_shared(remoteResultSet); + auto [status, resultSet] = service->RemoteQuery(syncerParam_, device, sql, selectionArgs); + errCode = status; + return resultSet; } std::shared_ptr RdbStoreImpl::Query(int &errCode, bool distinct, diff --git a/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp b/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp index c9e27c1f..38273ef3 100644 --- a/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp @@ -21,6 +21,7 @@ namespace OHOS::NativeRdb { using namespace OHOS::Rdb; +using Code = RemoteResultSet::Code; ResultSetProxy::ResultSetProxy(const sptr &impl) : IRemoteProxy(impl) { @@ -38,18 +39,20 @@ int ResultSetProxy::GetAllColumnNames(std::vector &columnNames) { MessageParcel data, reply; if (!data.WriteInterfaceToken(ResultSetProxy::GetDescriptor())) { - LOG_ERROR("Write descriptor failed, code is %{public}d.", CMD_GET_ALL_COLUMN_NAMES); + LOG_ERROR("Write descriptor failed, code is %{public}d.", Code::CMD_GET_ALL_COLUMN_NAMES); return E_ERROR; } MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = remote_->SendRequest(CMD_GET_ALL_COLUMN_NAMES, data, reply, mo); + int32_t error = remote_->SendRequest(Code::CMD_GET_ALL_COLUMN_NAMES, data, reply, mo); if (error != 0) { - LOG_ERROR("SendRequest failed, error is %{public}d, code is %{public}d.", error, CMD_GET_ALL_COLUMN_NAMES); + LOG_ERROR( + "SendRequest failed, error is %{public}d, code is %{public}d.", error, Code::CMD_GET_ALL_COLUMN_NAMES); return E_ERROR; } int status = reply.ReadInt32(); if (status != E_OK) { - LOG_ERROR("Reply status error, status is %{public}d, code is %{public}d.", status, CMD_GET_ALL_COLUMN_NAMES); + LOG_ERROR( + "Reply status error, status is %{public}d, code is %{public}d.", status, Code::CMD_GET_ALL_COLUMN_NAMES); return status; } if (!reply.ReadStringVector(&columnNames)) { @@ -61,13 +64,13 @@ int ResultSetProxy::GetAllColumnNames(std::vector &columnNames) int ResultSetProxy::GetColumnCount(int &count) { - return SendRequestRetInt(CMD_GET_COLUMN_COUNT, count); + return SendRequestRetInt(Code::CMD_GET_COLUMN_COUNT, count); } int ResultSetProxy::GetColumnType(int columnIndex, ColumnType &columnType) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_COLUMN_TYPE, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_COLUMN_TYPE, columnIndex, reply); if (status != E_OK) { return status; } @@ -79,22 +82,22 @@ int ResultSetProxy::GetColumnIndex(const std::string &columnName, int &columnInd { MessageParcel data, reply; if (!data.WriteInterfaceToken(ResultSetProxy::GetDescriptor())) { - LOG_ERROR("Write descriptor failed, code is %{public}d.", CMD_GET_COLUMN_INDEX); + LOG_ERROR("Write descriptor failed, code is %{public}d.", Code::CMD_GET_COLUMN_INDEX); return E_ERROR; } if (!reply.SetMaxCapacity(MAX_IPC_CAPACITY) || !data.WriteString(columnName)) { - LOG_ERROR("Set max capacity failed or write parcel failed, code is %{public}d.", CMD_GET_COLUMN_INDEX); + LOG_ERROR("Set max capacity failed or write parcel failed, code is %{public}d.", Code::CMD_GET_COLUMN_INDEX); return E_ERROR; } MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = remote_->SendRequest(CMD_GET_COLUMN_INDEX, data, reply, mo); + int32_t error = remote_->SendRequest(Code::CMD_GET_COLUMN_INDEX, data, reply, mo); if (error != 0) { - LOG_ERROR("SendRequest failed, error is %{public}d, code is %{public}d.", error, CMD_GET_COLUMN_INDEX); + LOG_ERROR("SendRequest failed, error is %{public}d, code is %{public}d.", error, Code::CMD_GET_COLUMN_INDEX); return E_ERROR; } int status = reply.ReadInt32(); if (status != E_OK) { - LOG_ERROR("Reply status error, status is %{public}d, code is %{public}d.", status, CMD_GET_COLUMN_INDEX); + LOG_ERROR("Reply status error, status is %{public}d, code is %{public}d.", status, Code::CMD_GET_COLUMN_INDEX); return status; } columnIndex = reply.ReadInt32(); @@ -104,7 +107,7 @@ int ResultSetProxy::GetColumnIndex(const std::string &columnName, int &columnInd int ResultSetProxy::GetColumnName(int columnIndex, std::string &columnName) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_COLUMN_NAME, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_COLUMN_NAME, columnIndex, reply); if (status != E_OK) { return status; } @@ -114,68 +117,68 @@ int ResultSetProxy::GetColumnName(int columnIndex, std::string &columnName) int ResultSetProxy::GetRowCount(int &count) { - return SendRequestRetInt(CMD_GET_ROW_COUNT, count); + return SendRequestRetInt(Code::CMD_GET_ROW_COUNT, count); } int ResultSetProxy::GetRowIndex(int &position) const { - return SendRequestRetInt(CMD_GET_ROW_INDEX, position); + return SendRequestRetInt(Code::CMD_GET_ROW_INDEX, position); } int ResultSetProxy::GoTo(int offset) { - return SendIntRequest(CMD_GO_TO, offset); + return SendIntRequest(Code::CMD_GO_TO, offset); } int ResultSetProxy::GoToRow(int position) { - return SendIntRequest(CMD_GO_TO_ROW, position); + return SendIntRequest(Code::CMD_GO_TO_ROW, position); } int ResultSetProxy::GoToFirstRow() { - return SendRequest(CMD_GO_TO_FIRST_ROW); + return SendRequest(Code::CMD_GO_TO_FIRST_ROW); } int ResultSetProxy::GoToLastRow() { - return SendRequest(CMD_GO_TO_LAST_ROW); + return SendRequest(Code::CMD_GO_TO_LAST_ROW); } int ResultSetProxy::GoToNextRow() { - return SendRequest(CMD_GO_TO_NEXT_ROW); + return SendRequest(Code::CMD_GO_TO_NEXT_ROW); } int ResultSetProxy::GoToPreviousRow() { - return SendRequest(CMD_GO_TO_PREV_ROW); + return SendRequest(Code::CMD_GO_TO_PREV_ROW); } int ResultSetProxy::IsEnded(bool &result) { - return SendRequestRetBool(CMD_IS_ENDED_ROW, result); + return SendRequestRetBool(Code::CMD_IS_ENDED_ROW, result); } int ResultSetProxy::IsStarted(bool &result) const { - return SendRequestRetBool(CMD_IS_STARTED_ROW, result); + return SendRequestRetBool(Code::CMD_IS_STARTED_ROW, result); } int ResultSetProxy::IsAtFirstRow(bool &result) const { - return SendRequestRetBool(CMD_IS_AT_FIRST_ROW, result); + return SendRequestRetBool(Code::CMD_IS_AT_FIRST_ROW, result); } int ResultSetProxy::IsAtLastRow(bool &result) { - return SendRequestRetBool(CMD_IS_AT_LAST_ROW, result); + return SendRequestRetBool(Code::CMD_IS_AT_LAST_ROW, result); } int ResultSetProxy::GetBlob(int columnIndex, std::vector &blob) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_BLOB, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_BLOB, columnIndex, reply); if (status != E_OK) { return status; } @@ -189,7 +192,7 @@ int ResultSetProxy::GetBlob(int columnIndex, std::vector &blob) int ResultSetProxy::GetString(int columnIndex, std::string &value) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_STRING, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_STRING, columnIndex, reply); if (status != E_OK) { return status; } @@ -200,7 +203,7 @@ int ResultSetProxy::GetString(int columnIndex, std::string &value) int ResultSetProxy::GetInt(int columnIndex, int &value) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_INT, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_INT, columnIndex, reply); if (status != E_OK) { return status; } @@ -211,7 +214,7 @@ int ResultSetProxy::GetInt(int columnIndex, int &value) int ResultSetProxy::GetLong(int columnIndex, int64_t &value) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_LONG, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_LONG, columnIndex, reply); if (status != E_OK) { return status; } @@ -222,7 +225,7 @@ int ResultSetProxy::GetLong(int columnIndex, int64_t &value) int ResultSetProxy::GetDouble(int columnIndex, double &value) { MessageParcel reply; - int status = SendRequestRetReply(CMD_GET_DOUBLE, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_GET_DOUBLE, columnIndex, reply); if (status != E_OK) { return status; } @@ -238,7 +241,7 @@ int ResultSetProxy::GetSize(int columnIndex, size_t &size) int ResultSetProxy::IsColumnNull(int columnIndex, bool &isNull) { MessageParcel reply; - int status = SendRequestRetReply(CMD_IS_COLUMN_NULL, columnIndex, reply); + int status = SendRequestRetReply(Code::CMD_IS_COLUMN_NULL, columnIndex, reply); if (status != E_OK) { return status; } @@ -246,7 +249,7 @@ int ResultSetProxy::IsColumnNull(int columnIndex, bool &isNull) return E_OK; } -int ResultSetProxy::GetRow(RowEntity &rowEntity) +int ResultSetProxy::GetRow(NativeRdb::RowEntity &rowEntity) { return E_NOT_SUPPORT; } @@ -255,13 +258,13 @@ bool ResultSetProxy::IsClosed() const { MessageParcel data, reply; if (!data.WriteInterfaceToken(ResultSetProxy::GetDescriptor())) { - LOG_ERROR("Write descriptor failed, code is %{public}d.", CMD_IS_CLOSED); + LOG_ERROR("Write descriptor failed, code is %{public}d.", Code::CMD_IS_CLOSED); return false; } MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = remote_->SendRequest(CMD_IS_CLOSED, data, reply, mo); + int32_t error = remote_->SendRequest(Code::CMD_IS_CLOSED, data, reply, mo); if (error != 0) { - LOG_ERROR("SendRequest failed, error is %{public}d, code is %{public}d.", error, CMD_IS_CLOSED); + LOG_ERROR("SendRequest failed, error is %{public}d, code is %{public}d.", error, Code::CMD_IS_CLOSED); return false; } return reply.ReadBool(); @@ -269,7 +272,7 @@ bool ResultSetProxy::IsClosed() const int ResultSetProxy::Close() { - return SendRequest(CMD_CLOSE); + return SendRequest(Code::CMD_CLOSE); } int ResultSetProxy::SendRequest(uint32_t code) diff --git a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp index f31e5b00..2cdc3ba0 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp @@ -20,6 +20,7 @@ #include "logger.h" #include "sqlite3sym.h" +#include "sqlite_utils.h" namespace OHOS { namespace NativeRdb { @@ -58,6 +59,8 @@ void SqliteGlobalConfig::SqliteLogCallback(const void *data, int err, const char if (verboseLog) { LOG_INFO("SQLite Error(%{public}d) %{public}s ", err, msg); } + } else if (errType == SQLITE_WARNING) { + LOG_WARN("SQLite WARNING(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } else { LOG_ERROR("SQLite Error(%{public}d) %{public}s", err, msg); } diff --git a/relational_store/interfaces/inner_api/cloud_data/include/cloud_types.h b/relational_store/interfaces/inner_api/cloud_data/include/cloud_types.h index ded2571a..4897953a 100644 --- a/relational_store/interfaces/inner_api/cloud_data/include/cloud_types.h +++ b/relational_store/interfaces/inner_api/cloud_data/include/cloud_types.h @@ -56,6 +56,8 @@ using Participants = std::vector; using Results = std::tuple>>; using QueryResults = std::tuple; +constexpr const char *DATA_CHANGE_EVENT_ID = "cloud_data_change"; + /** * Enumerates the error code of sharing invitation. */ diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h index 92a78ddd..ae6766fe 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h @@ -19,15 +19,12 @@ #include #include +#include "result_set.h" #include "rdb_types.h" #include "rdb_notifier.h" #include "distributeddata_relational_store_ipc_interface_code.h" -#include "values_bucket.h" namespace OHOS { -template -class sptr; -class IRemoteObject; namespace DistributedRdb { class RdbService { public: @@ -37,6 +34,7 @@ public: bool isAsync = false; bool isAutoSync = false; }; + using ResultSet = NativeRdb::ResultSet; virtual std::string ObtainDistributedTableName(const std::string &device, const std::string &table) = 0; @@ -59,8 +57,8 @@ public: virtual int32_t UnregisterAutoSyncCallback( const RdbSyncerParam ¶m, std::shared_ptr observer) = 0; - virtual int32_t RemoteQuery(const RdbSyncerParam ¶m, const std::string &device, const std::string &sql, - const std::vector &selectionArgs, sptr &resultSet) = 0; + virtual std::pair> RemoteQuery(const RdbSyncerParam ¶m, + const std::string &device, const std::string &sql, const std::vector &selectionArgs) = 0; virtual int32_t InitNotifier(const RdbSyncerParam ¶m, sptr notifier) = 0; @@ -69,7 +67,7 @@ public: // only use param.storeName_ virtual int32_t Delete(const RdbSyncerParam ¶m) = 0; - virtual std::pair> QuerySharingResource( + virtual std::pair> QuerySharingResource( const RdbSyncerParam ¶m, const PredicatesMemo &predicates, const std::vector &columns) = 0; virtual int32_t NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData) = 0; diff --git a/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h b/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h index b8f21ea6..ca9a5736 100644 --- a/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h @@ -54,7 +54,7 @@ public: /** * @brief The error CMD in the correct case. */ - enum { + enum Code { /** Indicates the current CMD is CMD_GET_ALL_COLUMN_NAMES.*/ CMD_GET_ALL_COLUMN_NAMES, /** Indicates the current CMD is CMD_GET_COLUMN_COUNT.*/ diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js index d9ca41e1..35dd86a2 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreCustomDir.test.js @@ -47,6 +47,18 @@ const STORE_CONFIG4 = { customDir: "custom".repeat(30), // customDir length exceeds 128 bytes }; +const STORE_CONFIG5 = { + name: "RdbCustomDir5.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "/custom", // customDir must be a relative directory +}; + +const STORE_CONFIG6 = { + name: "RdbCustomDir6".repeat(80) + ".db", + securityLevel: data_relationalStore.SecurityLevel.S1, + customDir: "custom", // database path exceeds 1024 bytes +}; + const asset1 = { name: "name1", uri: "uri1", @@ -85,6 +97,9 @@ describe('rdbStoreCustomTest', function () { await data_relationalStore.deleteRdbStore(context, STORE_CONFIG1); await data_relationalStore.deleteRdbStore(context, STORE_CONFIG2); await data_relationalStore.deleteRdbStore(context, STORE_CONFIG3); + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG4); + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG5); + await data_relationalStore.deleteRdbStore(context, STORE_CONFIG6); store = null; }) @@ -142,6 +157,9 @@ describe('rdbStoreCustomTest', function () { * @tc.name Normal test case of getRdbStore, test single-layer directory * @tc.desc 1.Configure customDir * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0001', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0001 start *************"); @@ -159,10 +177,13 @@ describe('rdbStoreCustomTest', function () { /** * @tc.number testRdbStoreCustomDirTest0002 - * @tc.name Normal test case of deleteRdbStore, Configure customDir + * @tc.name Normal test case of deleteRdbStore, test create and delete database * @tc.desc 1.Configure customDir * 2.Execute getRdbStore * 3.Execute deleteRdbStore by StoreConfig + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0002', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0002 start *************"); @@ -195,6 +216,9 @@ describe('rdbStoreCustomTest', function () { * 3.Execute getRdbStore2 * 4.Execute deleteRdbStore1 * 5.Execute deleteRdbStore2 + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0003', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0003 start *************"); @@ -228,6 +252,9 @@ describe('rdbStoreCustomTest', function () { * 2.Execute getRdbStore * 3.Execute insert data * 4.Execute query data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0004', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0004 start *************"); @@ -270,6 +297,9 @@ describe('rdbStoreCustomTest', function () { * 3.Execute insert data * 4.Execute update data * 5.Execute query data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0005', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0005 start *************"); @@ -312,6 +342,9 @@ describe('rdbStoreCustomTest', function () { * @tc.name Normal test case of getRdbStore, if customDir is "" * @tc.desc 1.Configure customDir as "" * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0006', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0006 start *************"); @@ -338,6 +371,9 @@ describe('rdbStoreCustomTest', function () { * @tc.name Normal test case of deleteRdbStore, if customDir is null * @tc.desc 1.Configure customDir as null * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0007', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0007 start *************"); @@ -363,6 +399,9 @@ describe('rdbStoreCustomTest', function () { * @tc.name Normal test case of deleteRdbStore, if customDir is undefined * @tc.desc 1.Configure customDir as undefined * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0008', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0008 start *************"); @@ -389,6 +428,9 @@ describe('rdbStoreCustomTest', function () { * @tc.desc 1.Configure customDir * 2.Execute getRdbStore * 3.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ it('testRdbStoreCustomDirTest0009', 0, async function (done) { console.info(TAG, "************* testRdbStoreCustomDirTest0009 start *************"); @@ -414,13 +456,16 @@ describe('rdbStoreCustomTest', function () { }) /** - * @tc.number testRdbStoreCustomDirTest00010 - * @tc.name AbNormal test case of getRdbStore, if customDir length exceeds 128 bytes + * @tc.number testRdbStoreCustomDirTest0010 + * @tc.name Abnormal test case of getRdbStore, if customDir length exceeds 128 bytes * @tc.desc 1.Configure customDir * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 */ - it('testRdbStoreCustomDirTest00010', 0, async function (done) { - console.info(TAG, "************* testRdbStoreCustomDirTest00010 start *************"); + it('testRdbStoreCustomDirTest0010', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0010 start *************"); try { store = await data_relationalStore.getRdbStore(context, STORE_CONFIG4); expect(false).assertTrue(); @@ -429,7 +474,51 @@ describe('rdbStoreCustomTest', function () { expect("401").assertEqual(err.code); done(); } - console.info(TAG, "************* testRdbStoreCustomDirTest00010 end *************") + console.info(TAG, "************* testRdbStoreCustomDirTest0010 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0011 + * @tc.name Abnormal test case of getRdbStore, if customDir is a absolute directory + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('testRdbStoreCustomDirTest0011', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0011 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG5); + expect(false).assertTrue(); + } catch (err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect("401").assertEqual(err.code); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0011 end *************") + }) + + /** + * @tc.number testRdbStoreCustomDirTest0012 + * @tc.name Abnormal test case of getRdbStore, if database path exceeds 1024 bytes + * @tc.desc 1.Configure customDir + * 2.Execute getRdbStore + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('testRdbStoreCustomDirTest0012', 0, async function (done) { + console.info(TAG, "************* testRdbStoreCustomDirTest0012 start *************"); + try { + store = await data_relationalStore.getRdbStore(context, STORE_CONFIG6); + expect(false).assertTrue(); + } catch (err) { + console.error(TAG, "catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message); + expect("401").assertEqual(err.code); + done(); + } + console.info(TAG, "************* testRdbStoreCustomDirTest0012 end *************") }) console.info(TAG, "*************Unit Test End*************"); }) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 730a2c06..267b9038 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -62,6 +62,8 @@ target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/bootstrap/include) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/config/include) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/crypto/include) +target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/object) +target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/common) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/directory/include) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/matrix/include) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/data_share/common) @@ -74,6 +76,7 @@ target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/crypto/include) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/app/src/) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/frameworks/native/rdb/include/) +target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/interfaces/inner_api/rdb/include/) #************************************************DataMgrServiceTest start************************************************# #************************************************RDBTest start************************************************# -- Gitee From 20f81e50e499e74b10f23f85cbca49214ed3943b Mon Sep 17 00:00:00 2001 From: "1529367376@qq.com" Date: Wed, 13 Dec 2023 18:58:13 +0800 Subject: [PATCH 2/2] update Signed-off-by: 1529367376@qq.com --- bin/update/update.bat | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/update/update.bat b/bin/update/update.bat index ac060ee0..cab95e31 100644 --- a/bin/update/update.bat +++ b/bin/update/update.bat @@ -14,6 +14,12 @@ git clone https://gitee.com/openharmony/distributeddatamgr_kv_store.git ./tmp/kv git clone https://gitee.com/openharmony/distributeddatamgr_relational_store.git ./tmp/relational_store @echo "clone the data_object" git clone https://gitee.com/openharmony/distributeddatamgr_data_object.git ./tmp/data_object +@echo "clone the data_share" +git clone https://gitee.com/openharmony/distributeddatamgr_data_share.git ./tmp/data_share +@echo "clone the preferences" +git clone https://gitee.com/openharmony/distributeddatamgr_preferences.git ./tmp/preferences +@echo "clone the udmf" +git clone https://gitee.com/openharmony/distributeddatamgr_udmf.git ./tmp/udmf xcopy tmp\* ..\..\ /y /e /i /q -- Gitee